From 96911c997f6c7d57b1d9ac45a97e33394900cd83 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 15 Mar 2017 12:21:13 -0300 Subject: [PATCH 01/57] 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 02/57] =?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 03/57] =?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 04/57] 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 05/57] =?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 8675c4203e88e465cb6dd7f578530a25f0a5b7a2 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 10 Apr 2017 15:13:45 -0300 Subject: [PATCH 06/57] 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 451e2949a544524dbaaa30baae3e4b5abcc4f7f9 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 12 Apr 2017 13:14:40 -0300 Subject: [PATCH 07/57] 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 08/57] =?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 09/57] =?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 10/57] =?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 11/57] =?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 12/57] =?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 13/57] =?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 14/57] 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 15/57] =?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 16/57] =?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) From 96ce98f29d7bbdf9131e8e14678d6d4c382df020 Mon Sep 17 00:00:00 2001 From: Edward Date: Thu, 20 Apr 2017 10:11:43 -0300 Subject: [PATCH 17/57] Docker sapl 2 (#1023) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adiciona dDocker 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 * Refazer Dockerfile * Ajusta Dockerfile e docker-compose com entrypoint start.sh * Ajusta start.sh * Adiciona mais pontos de montagem. * Coloca start.sh como executável: chmod +x start.sh * Remove arquivo lixo * Substitui gen-env.py por shell script puro * Ajusta diretorio /var/interlegis/sapl e collect_static como volume no nginix * Simplifica criação de diretórios. * Adiciona ponto de montagem em postgres para importar dados * Adiciona mais parâmetros de ambiente UNIX para entrypoint docker --- .gitignore | 4 +- .travis.yml | 4 ++ Dockerfile | 75 ++++++++++++------------------- busy-wait.sh | 10 +++++ config/env-sample | 8 ++++ config/nginx/sapl.conf | 39 ++++++++++++++++ docker-compose.yml | 26 ++++++++--- docker-env.sh | 6 +++ envfile | 1 + genkey.py | 7 +++ gunicorn_start.sh | 10 +---- sapl/.env_test | 2 +- sapl/static/styles/app.css | 1 + sapl/static/styles/compilacao.css | 1 + scripts_docker/shell_sapl.sh | 3 +- start.sh | 53 ++++++++++++++++++++++ 16 files changed, 186 insertions(+), 64 deletions(-) create mode 100644 busy-wait.sh create mode 100644 config/env-sample create mode 100644 config/nginx/sapl.conf create mode 100644 docker-env.sh create mode 100644 envfile create mode 100644 genkey.py create mode 100644 sapl/static/styles/app.css create mode 100644 sapl/static/styles/compilacao.css create mode 100755 start.sh diff --git a/.gitignore b/.gitignore index 83de47a86..52baa1622 100644 --- a/.gitignore +++ b/.gitignore @@ -92,4 +92,6 @@ collected_static bower bower_components media -whoosh/ \ No newline at end of file +whoosh/ +postgres-data/ +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..6551f656b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,53 +1,34 @@ -FROM ubuntu:15.04 - -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 mkdir /sapl - -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 +FROM alpine:3.5 + +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 vim + +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 -p /var/interlegis/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 /var/interlegis/sapl/ + +ADD . /var/interlegis/sapl/ -WORKDIR /sapl +COPY start.sh /var/interlegis/sapl/ -ADD . /sapl +RUN chmod +x /var/interlegis/sapl/start.sh -RUN pip install -r requirements/dev-requirements.txt -RUN pip install --upgrade setuptools +RUN pip install -r /var/interlegis/sapl/requirements/requirements.txt --upgrade setuptools -# RUN python3 manage.py bower install +VOLUME ["/var/interlegis/sapl/data", "/var/interlegis/sapl/media", "/var/interlegis/sapl/collected_static"] +ENTRYPOINT ["/var/interlegis/sapl/start.sh"] 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/env-sample b/config/env-sample new file mode 100644 index 000000000..c358f9017 --- /dev/null +++ b/config/env-sample @@ -0,0 +1,8 @@ +DATABASE_URL = postgresql://postgres:@sapldb:/sapl +KEY +DEBUG = False +EMAIL_USE_TLS = True +EMAIL_PORT = 587 +EMAIL_HOST = '' +EMAIL_HOST_USER = '' +EMAIL_HOST_PASSWORD = '' diff --git a/config/nginx/sapl.conf b/config/nginx/sapl.conf new file mode 100644 index 000000000..ef3dac421 --- /dev/null +++ b/config/nginx/sapl.conf @@ -0,0 +1,39 @@ +upstream sapl_server { + + server unix:/var/interlegis/sapl/run/gunicorn.sock fail_timeout=0; + +} + +server { + + listen 80; + server_name sapl.test; + + client_max_body_size 4G; + + location /static/ { + alias /var/interlegis/sapl/collected_static/; + } + + location /media/ { + alias /var/interlegis/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 /var/interlegis/sapl/sapl/static/; + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 8de57e3aa..a073bb4ee 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,31 @@ -localhost: +server: + image: nginx:latest + ports: + - "80:80" + volumes: + - ./config/nginx:/etc/nginx/conf.d + - ./collected_static:/var/interlegis/sapl/collected_static + - ./media:/var/interlegis/sapl/media + volumes_from: + - 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/ + - ./data:/data-import ports: - "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 /sapl" volumes: - - .:/sapl - ports: - - "8000:8000" + - .:/var/interlegis/sapl/ + - ./data:/var/interlegis/sapl/data + - ./media:/var/interlegis/sapl/media + - ./collected_static:/var/interlegis/sapl/collected_static links: - - localhost + - sapldb diff --git a/docker-env.sh b/docker-env.sh new file mode 100644 index 000000000..07528b0f1 --- /dev/null +++ b/docker-env.sh @@ -0,0 +1,6 @@ +#/bin/bash + +KEY=`python gen-key.py` +echo $KEY + +sed -e "s/SECRET_KEY = None/SECRET_KEY = $KEY/g" config/env-sample diff --git a/envfile b/envfile new file mode 100644 index 000000000..a7aef4b0f --- /dev/null +++ b/envfile @@ -0,0 +1 @@ +EMAIL_HOST_USER=foo diff --git a/genkey.py b/genkey.py new file mode 100644 index 000000000..85f399c54 --- /dev/null +++ b/genkey.py @@ -0,0 +1,7 @@ +import random + +def generate_secret(): + return ''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)]) + +if __name__ == '__main__': + print(generate_secret()) diff --git a/gunicorn_start.sh b/gunicorn_start.sh index 34147cb97..9669644fa 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -12,23 +12,17 @@ then fi NAME="SAPL" # Name of the application (*) -DJANGODIR=/var/interlegis/sapl # Django project directory (*) +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=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` 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 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/sapl/static/styles/app.css b/sapl/static/styles/app.css new file mode 100644 index 000000000..e7146b1f4 --- /dev/null +++ b/sapl/static/styles/app.css @@ -0,0 +1 @@ +.logo img{width:40px;height:40px;margin:5px 15px}.vcenter{display:inline-block;vertical-align:middle;float:none;padding:10px}nav.navbar{border-radius:0;font-size:15px}nav .navbar-nav>li>a{padding-top:0px;padding-bottom:0px;line-height:75px}nav .navbar-nav>li>a:hover{background-color:#23527c}nav .navbar-nav>li:nth-child(2)>.dropdown-menu{right:auto}nav .navbar-nav:last-child>li:last-child a{padding-right:0px}.masthead{padding:10px}.masthead .nav{clear:both}.masthead .navbar-brand{color:inherit;font-size:24px}.masthead .navbar-brand img.img-responsive{height:95px;margin-right:15px}.masthead .navbar-brand small{color:#93A4AA;font-size:75%;line-height:25px}.navbar{margin-bottom:0}.navbar-brand{padding:0px}h1,.h1{font-size:30px}h2,.h2{font-size:24px}h3,.h3{font-size:20px}h4,.h4{font-size:16px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}.page-header{margin:20px 0px 10px}.btn:hover,.btn:focus{color:inherit}.caret.top{transform:rotate(180deg)}.btn-default.btn-excluir{color:#d9534f}.btn-default.btn-excluir:hover{color:#fff;border-color:#de6764;background-color:#de6764}.controls-file{padding:10px;border:1px solid #d6e1e5;border-radius:4px}.controls-file label.checkbox-inline{margin:0px;display:block}.controls-radio-checkbox{padding:0px;border:1px solid #d6e1e5;border-radius:4px;min-height:20px}.controls-radio-checkbox .help-block{margin:15px;padding:15px;border:2px dashed #d6e1e5}.controls-radio-checkbox label{padding:5px}.controls-radio-checkbox label .icons{top:5px;left:8px}.controls-radio-checkbox label.checkbox-inline,.controls-radio-checkbox label.radio-inline{padding:8px;padding-left:36px}.controls-radio-checkbox label.checkbox-inline .icons,.controls-radio-checkbox label.radio-inline .icons{top:8px;left:8px}.controls-radio-checkbox .checkbox,.controls-radio-checkbox .radio,.controls-radio-checkbox .checkbox-inline,.controls-radio-checkbox .radio-inline{margin:0}.controls-radio-checkbox .checkbox:hover,.controls-radio-checkbox .radio:hover,.controls-radio-checkbox .checkbox-inline:hover,.controls-radio-checkbox .radio-inline:hover{background-color:#d6e1e5}p.control-label{font-weight:bold}.legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5;clear:both}.grid-gutter-width-right{margin-right:15px}html{position:relative;min-height:100%}body{margin-bottom:160px}.footer{position:absolute;bottom:0;width:100%;height:140px;background:#364347 none repeat scroll 0% 0%;color:white;text-align:center}.footer p{color:white;margin-top:10px}.footer .container{padding-top:25px}.pagination{padding-top:25px}.modal .alert{margin-bottom:0}fieldset fieldset{font-size:95%}fieldset fieldset legend{font-size:18px}.avatar-parlamentar{height:84px;width:84px}#conteudo{position:relative;padding:2em 1.5em 1.5em 1.5em;overflow:hidden;font-size:100%;text-align:left;min-height:350px;max-width:1000px;margin:0 auto}#conteudo a:hover{color:#444;-webkit-transition:0.3s ease-in;-moz-transition:0.3s ease-in;-o-transition:0.3s ease-in}#homeIndex{text-align:center}.homeBanner span{color:white;font-size:32px;font-weight:600;display:inline-block;vertical-align:middle;padding:2px 45px 4px;border:2px solid}.homeBanner::after{display:inline-block;vertical-align:middle;height:100%}.homeBlock{display:inline-block;position:relative;background-color:#F3F3F3;width:190px;height:260px;margin:3px;text-align:center;font-size:0;overflow:hidden}.homeBlock>a{display:block;position:absolute;width:100%;height:100%;top:0;left:0}.homeBlock::after{content:'';display:inline-block;vertical-align:middle;height:100%;overflow:visible;clear:none;visibility:initial}.homeContent{position:relative;padding:10px;text-align:justify;font-size:14px;color:#FFF;opacity:0;transition:opacity 0.5s ease;display:inline-block;vertical-align:middle}.homeContent p{display:block;line-height:13px;font-size:80%;color:white}.homeIcon{position:relative;display:inline-block;width:105px;height:105px;border-radius:50%;background:#364347;z-index:1}.homeIcon::before{content:'';position:absolute;width:100%;height:100%;border-radius:50%;background:#364347;top:0;left:0;transform:scale(0.95);transition:transform 0.6s ease}.homeIcon img{position:absolute;margin:auto;top:0;bottom:0;right:0;left:0;transition:opacity 0.4s 0.4s ease}.homeFront{position:absolute;top:46%;width:100%;font-size:0;transform:translateY(-60%)}.homeFront h2{position:absolute;margin-top:18px;font-size:22px;font-weight:700;color:#595959 !important;width:100%;padding:0 6%;z-index:0}.homeTitle{display:block;height:32px;text-align:center;width:100%;opacity:0;transition:opacity 0.4s ease}.homeTitle::before{content:'';display:inline-block;vertical-align:middle;height:100%}.homeTitle h2{display:inline-block;vertical-align:middle;max-width:110px;font-size:14px;color:white !important;line-height:1em}.homeTitle img{display:inline-block;vertical-align:middle;height:30px;margin-right:5px}.homeBlock:hover .homeIcon::before{transform:scale(3.6) translateY(7px)}.homeBlock:hover .homeContent{opacity:1;transition-delay:0.2s}.homeBlock:hover .homeIcon img{opacity:0;transition-duration:0.2s;transition-delay:0s}.homeBlock:hover .homeTitle{opacity:1}h1,h2,h3,h4,h5,h6,form,dl,dt,dd,p,div,img,a{margin:0;padding:0}p{margin:0.5em 0}.manual li{display:list-item;line-height:1.5em;padding-right:0}.manual li a{background-color:transparent;border:none;border-radius:none;padding:0}.manual,.manual ul{padding-left:1.5em;list-style-type:none;margin-top:0;font-size:100%}@media (max-width: 1199px){.masthead .navbar-brand{font-size:22px}.masthead .navbar-brand img.img-responsive{height:60px;width:60px;margin-right:7.5px}.navbar-nav>li>a{padding-left:10.71429px;padding-right:10.71429px}}@media (max-width: 1091px){.navbar-nav>li>a{padding-left:7.5px;padding-right:7.5px}}@media (min-width: 1092px) and (max-width: 1199px){.container{width:1070px}} diff --git a/sapl/static/styles/compilacao.css b/sapl/static/styles/compilacao.css new file mode 100644 index 000000000..ed50d8998 --- /dev/null +++ b/sapl/static/styles/compilacao.css @@ -0,0 +1 @@ +a:link:after,a:visited:after{content:""}.test_import:nth-child(even){background-color:#ccc}#wait_message{display:block;position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(220,220,220,0.75);z-index:99}#wait_message #msg{position:relative;margin:20% auto;padding:1.2em 2em;max-width:600px;text-align:center;font-size:1.5em;color:#677;border:1px solid #eee;background-color:#fff !important;box-shadow:0 1px 2px #999}.text-center{text-align:center}.cp-notify{z-index:9999;position:fixed;top:2em;left:50%;min-width:600px;transform:translate(-50%, 0);transition:all 0.4s ease;opacity:0.97}.cp-notify.hide{opacity:0;top:-1000px;display:block !important;transition:all 0.4s ease}.cp-notify .message{padding:1em;border:2px solid rgba(0,0,0,0.1);border-radius:4px;color:rgba(0,0,0,0.6);line-height:1em;font-size:1.3em;text-align:center;box-shadow:0 0 100px rgba(0,0,0,0.2)}.cp .desativado .dtxt,.cp .dpt .dptt>a.desativado .dtxt,.cp .desativado .dtxt *,.cp .dpt .dptt>a.desativado .dtxt *,.cp .desativado .dpt-link,.cp .dpt .dptt>a.desativado .dpt-link,.cp .desativado .dpt-link *,.cp .dpt .dptt>a.desativado .dpt-link *{text-decoration:line-through;color:#999 !important}.cp .desativado .dtxt table,.cp .dpt .dptt>a.desativado .dtxt table,.cp .desativado .dtxt table td,.cp .dpt .dptt>a.desativado .dtxt table td,.cp .desativado .dtxt * table,.cp .dpt .dptt>a.desativado .dtxt * table,.cp .desativado .dtxt * table td,.cp .dpt .dptt>a.desativado .dtxt * table td,.cp .desativado .dpt-link table,.cp .dpt .dptt>a.desativado .dpt-link table,.cp .desativado .dpt-link table td,.cp .dpt .dptt>a.desativado .dpt-link table td,.cp .desativado .dpt-link * table,.cp .dpt .dptt>a.desativado .dpt-link * table,.cp .desativado .dpt-link * table td,.cp .dpt .dptt>a.desativado .dpt-link * table td{border:1px dotted #ccc}.cp a{text-decoration:none;cursor:pointer}.cp .diff .desativado,.cp .diff .dpt .dptt>a.desativado,.cp .dpt .diff .dptt>a.desativado,.cp .diff .desativado *,.cp .diff .dpt .dptt>a.desativado *,.cp .dpt .diff .dptt>a.desativado *{text-decoration:line-through;color:#ddd !important;font-size:90%}.cp .diff .added{color:#04DE2C}.cp .dpt{font-size:1em;position:relative}.cp .dpt.indent{padding-left:1em}.cp .dpt .ementa{padding:2em 0em 2em 35%;font-weight:bold}.cp .dpt .titulo_generico,.cp .dpt .anexo,.cp .dpt .disp_preliminares,.cp .dpt .disp_gerais,.cp .dpt .disp_transitorias,.cp .dpt .disp_finais,.cp .dpt .parte,.cp .dpt .livro,.cp .dpt .titulo,.cp .dpt .capitulo,.cp .dpt .secao,.cp .dpt .subsecao,.cp .dpt .itemsecao{text-align:center;font-weight:bold;margin-bottom:1em;font-size:1.5em;margin-top:3em}.cp .dpt .titulo{margin-top:2em}.cp .dpt .capitulo{margin-top:1.5em;font-size:1.3em}.cp .dpt .secao{margin-top:1.2em;margin-bottom:0.7em;font-size:1.2em}.cp .dpt .subsecao,.cp .dpt .itemsecao{margin-top:1em;margin-bottom:0.6em;font-size:1.2em;font-style:italic}.cp .dpt .artigo{font-size:1.15em;float:left}.cp .dpt .artigo .dptt{position:relative}.cp .dpt .caput{margin-top:0.3333em;font-size:1.15em}.cp .dpt .paragrafo{font-size:1.1em;margin-top:0.2222em}.cp .dpt .inciso{font-size:1.1em;margin-top:0.1667em}.cp .dpt .alinea{font-size:1.0em;margin-top:2px}.cp .dpt .item{font-size:1.0em;margin-top:2px}.cp .dpt .bloco_alteracao{padding-left:10%;font-style:italic;color:#018}.cp .dpt .bloco_alteracao a{text-decoration:underline}.cp .dpt .bloco_alteracao a,.cp .dpt .bloco_alteracao table,.cp .dpt .bloco_alteracao table td{color:#018 !important}.cp .dpt .dn{font-weight:normal;position:relative;font-size:70%}.cp .dpt .dn p,.cp .dpt .dn ul{font-weight:normal;margin:0 0 0 0;list-style:none;padding:0}.cp .dpt .dn .dnl{display:block;text-align:left !important}.cp .dpt .dn .dnl *{display:inline}.cp .dpt .dn .dnl .bullet{padding:0 0.333em;display:inline-block}.cp .dpt .dn .dnl .dnli{min-height:2.5em}.cp .dpt .dn .dnl .dnli:hover ul{transition:opacity 0.5s linear, clip 0s 0.3s;clip:auto;opacity:1;background:rgba(230,230,230,0.9)}.cp .dpt .dn .dnl .dnli ul{transition:opacity 0.5s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;background:transparent;right:0;padding:0.2em 0.5em 0em 0.5em;border:1px solid #c7e3d3;border-top:0px;font-size:1.5rem}.cp .dpt .dn .dnl .dnli ul li{display:table-cell;color:#aaa}.cp .dpt .dn .dnl .dnli ul li:hover{color:#787}.cp .dpt .dn .dnl .dnli ul li:hover a{color:#27AE60 !important}.cp .dpt .dn .dnl .dnli ul li .nowner{color:#27AE60 !important}.cp .dpt .dn .dnl .dnli .ntitulo{font-weight:bold;color:#03A203;text-decoration:none}.cp .dpt .dn .dnl .dnli .ntitulo a{color:#294 !important}.cp .dpt .dn .dnl .dnli .ntexto{color:#06D806}.cp .dpt .dn .dnl .dnli .ntexto a{color:#03A203 !important}.cp .dpt .dn .dnl:hover{display:block}.cp .dpt .dn .dnl:hover *{display:block}.cp .dpt .dn .dnl:hover>.bullet{display:none}.cp .dpt .dn .dnl:hover .dnli{margin-top:0.5em;border-top:1px solid #c7e3d3}.cp .dpt .dptt>a{color:#444444}.cp .dpt .dptt>a.nota-alteracao{color:#02baf2;font-size:0.75em}.cp .dpt .dptt>a.nota-alteracao:hover{text-decoration:underline}.cp .dpt .dptt .dne{position:absolute;display:block;right:0;left:0;top:0;height:0;transform:scaleX(0);transform-origin:right;transition:all 0.3s ease;border-top:1px solid #2980B9}.cp .dpt .dptt .dne ul.btns-action{list-style:none;padding:0;position:absolute;right:0;background-color:#2980B9}.cp .dpt .dptt .dne ul.btns-action li{float:left}.cp .dpt .dptt .dne ul.btns-action li:hover{background-color:rgba(0,0,0,0.1)}.cp .dpt .dptt .dne ul.btns-action li a{color:white;padding:0.15em 1em 0;display:inline-block}.cp .dpt .dptt .dne-nota{position:relative;transform:scaleX(1);height:auto;border-top:0px}.cp .dpt .dptt .dne-nota ul.btns-action{display:none}.cp .dpt .dptt .dne-nota .dne-form{margin:1em -2em 0em;text-align:left;font-size:1.6rem}.cp .dpt .dptt:hover .dne{height:0.1667rem;transform:scaleX(1);transition-delay:1s}.cp .dpt .dptt:hover .dne-nota{height:auto;transition-delay:0s}.cp .tipo-vigencias{list-style:none;position:fixed;bottom:0px;left:50%;transform:translate(-50%, 0);margin:0;padding:0;background-color:#2980B9;z-index:1000;opacity:0.9;transition:all 0.3s ease-in-out}.cp .tipo-vigencias li{display:inline-block;border-left:1px solid #fff;float:left}.cp .tipo-vigencias li a{color:white;padding:0.3em 1em 0;display:inline-block;font-size:110%;cursor:pointer}.cp .tipo-vigencias li a.selected{background-color:rgba(0,0,0,0.5)}.cp .tipo-vigencias li:hover{background-color:rgba(0,0,0,0.2)}.cp .tipo-vigencias:hover{opacity:1}.cp.cpe .desativado,.cp.cpe .dpt .dptt>a.desativado{text-decoration:line-through;color:#999 !important}.cp.cpe .desativado table,.cp.cpe .dpt .dptt>a.desativado table,.cp.cpe .desativado table td,.cp.cpe .dpt .dptt>a.desativado table td{border:1px dotted #ccc}.cp.cpe .desativado a.nota-alteracao *{color:#02baf2 !important}.cp.cpe .dpt{display:block}.cp.cpe .dpt>.dpt-actions-fixed{position:absolute;right:-0.8em;top:-0.8em;z-index:3;opacity:0}.cp.cpe .dpt>.dpt-actions-fixed .activate{display:none}.cp.cpe .dpt>.dpt-actions-fixed .deactivate{display:inline}.cp.cpe .dpt>.dpt-actions-fixed .btn-dpt-edit.btn-default{color:#333}.cp.cpe .dpt>.dpt-actions-fixed .btn-dpt-edit.btn-default:hover{color:#fff;background-color:#02baf2}.cp.cpe .dpt>.dpt-actions,.cp.cpe .dpt>.dpt-actions-bottom{display:none}.cp.cpe .dpt>.dpt-text{cursor:text;min-height:30px;border:1px solid transparent}.cp.cpe .dpt>.dpt-text:hover,.cp.cpe .dpt>.dpt-text.hover-fixed{background-color:rgba(0,0,0,0.01);color:#2980B9;border:1px solid #eee;transition:color 0.3s ease}.cp.cpe .dpt>.dpt-text.artigo{float:none}.cp.cpe .dpt>.dpt-text a.link-rotulo{color:#000}.cp.cpe .dpt:hover>.dpt-actions-fixed{opacity:1}.cp.cpe .dpt:hover>.dpt-actions-fixed:hover ~ .dpt-text{background-color:rgba(0,0,0,0.01);color:#2980B9;border:1px solid #eee;transition:color 0.3s ease}.cp.cpe .dpt .semtexto{font-weight:bold;color:#9aaed6}.cp.cpe .dpt .semtexto:hover{color:#5f76a4}.cp.cpe .dpt-alts{margin:0;margin-bottom:1em;padding:0;background-color:transparent;min-height:100px;border:2px dashed #fff}.cp.cpe .dpt-alts:hover{border-color:#d9ddde}.cp.cpe .dpt-alts:empty{border-color:#ddd}.cp.cpe .dpt-alts.drag{width:100% !important;border-color:#d9ddde}.cp.cpe .dpt-alts.drag .dpt{transition-duration:0s !important}.cp.cpe .dpt-alts .dpt{width:100% !important;box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,0.12),0 2px 4px rgba(0,0,0,0.24);padding:0;margin:0;background-color:#edf0f1;height:auto !important;min-height:2em;z-index:1}.cp.cpe .dpt-alts .dpt:not(:first-child){border-top:1px solid white}.cp.cpe .dpt-alts .dpt>.dpt-text{padding:0.3em 1em;margin-top:0;margin-bottom:0}.cp.cpe .dpt-alts .dpt>.dpt-text a.link-rotulo{text-decoration:underline}.cp.cpe .dpt-alts .dpt-selected.dpt{margin:0em -0.5em}.cp.cpe .dpt-selected.dpt{width:auto !important;margin:1em -0.5em;border:1px solid #fad46b !important;padding:0;background-color:#fafafa;border-radius:3px;z-index:4}.cp.cpe .dpt-selected.dpt>.dpt-text{border:1px solid transparent}.cp.cpe .dpt-selected.dpt>.dpt-text:hover{border:1px solid transparent;background-color:transparent}.cp.cpe .dpt-selected.dpt>.dpt-form{margin-bottom:0em}.cp.cpe .dpt-selected.dpt>.dpt-actions,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom{display:table;background-color:#e5e5e5;padding:1em;margin-bottom:0em;width:100%}.cp.cpe .dpt-selected.dpt>.dpt-actions>.btn-action,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom>.btn-action{display:table-cell;float:none}.cp.cpe .dpt-selected.dpt>.dpt-actions .btn-excluir,.cp.cpe .cp.cpe1_old_apagar .dpt-selected.dpt>.dpt-actions .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1_old_apagar .cp.cpe .dpt-selected.dpt>.dpt-actions .csform .actions_inserts>li>a.btn-salvar,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .btn-excluir,.cp.cpe .cp.cpe1_old_apagar .dpt-selected.dpt>.dpt-actions-bottom .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1_old_apagar .cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .csform .actions_inserts>li>a.btn-salvar{display:inline-block;opacity:0.3}.cp.cpe .dpt-selected.dpt>.dpt-actions .btn-excluir:hover,.cp.cpe .cp.cpe1_old_apagar .dpt-selected.dpt>.dpt-actions .csform .actions_inserts>li>a.btn-salvar:hover,.cp.cpe1_old_apagar .cp.cpe .dpt-selected.dpt>.dpt-actions .csform .actions_inserts>li>a.btn-salvar:hover,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .btn-excluir:hover,.cp.cpe .cp.cpe1_old_apagar .dpt-selected.dpt>.dpt-actions-bottom .csform .actions_inserts>li>a.btn-salvar:hover,.cp.cpe1_old_apagar .cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .csform .actions_inserts>li>a.btn-salvar:hover{opacity:1}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom{margin:0}.cp.cpe .dpt-selected .dpt-block{border-top:1px solid #e5e5e5 !important;opacity:0.6;transition:opacity 0.4s ease}.cp.cpe .dpt-selected .dpt-block:hover{opacity:1}.cp.cpe .dpt-selected .dpt-text{opacity:0.7;margin:0;padding:0.7em}.cp.cpe .dpt-selected .dpt-text:hover{opacity:1;background-color:#f5f5f5}.cp.cpe .dpt-selected .dpt-alts{margin:1em}.cp.cpe .dpt-selected .dpt-alts .dpt{box-shadow:0 0 0}.cp.cpe .dpt-selected>.dpt-actions-fixed{opacity:1;top:-12px;right:0.5em}.cp.cpe .dpt-selected>.dpt-actions-fixed .activate{display:inline}.cp.cpe .dpt-selected>.dpt-actions-fixed .deactivate{display:none}.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit{padding-top:2px;padding-bottom:1px}.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit.btn-default{background-color:#fad46b;border:1px solid #fad46b}.cp.cpe .dpt-selected .dropdown-menu.dropdown-menu-left{right:auto !important;left:0;padding:2px 0}.cp.cpe .dpt-selected .dropdown-menu.dropdown-menu-left>.top.arrow{right:88%;left:auto}.cp.cpe .dpt-selected .dropdown-menu li a{padding-top:2px;padding-bottom:2px}.cp.cpe .dpt-selected .btn-group .radius-right{border-bottom-right-radius:4px !important;border-top-right-radius:4px !important}.cp.cpe .dpt-selected:hover>.dpt-actions-fixed{opacity:1}.cp.cpe1_old_apagar{margin-bottom:15em}.cp.cpe1_old_apagar .desativado,.cp.cpe1_old_apagar .dpt .dptt>a.desativado,.cp.cpe1_old_apagar .desativado *,.cp.cpe1_old_apagar .dpt .dptt>a.desativado *{text-decoration:line-through;color:#999 !important}.cp.cpe1_old_apagar .desativado table,.cp.cpe1_old_apagar .dpt .dptt>a.desativado table,.cp.cpe1_old_apagar .desativado table td,.cp.cpe1_old_apagar .dpt .dptt>a.desativado table td,.cp.cpe1_old_apagar .desativado * table,.cp.cpe1_old_apagar .dpt .dptt>a.desativado * table,.cp.cpe1_old_apagar .desativado * table td,.cp.cpe1_old_apagar .dpt .dptt>a.desativado * table td{border:1px dotted #ccc}.cp.cpe1_old_apagar a{text-decoration:none;cursor:pointer}.cp.cpe1_old_apagar .dpt{position:relative;display:block}.cp.cpe1_old_apagar .dpt .semtexto{font-weight:bold;color:#BFD1F6}.cp.cpe1_old_apagar .dpt .artigo{float:none}.cp.cpe1_old_apagar .dpt .caput{margin-top:0}.cp.cpe1_old_apagar .dpt>.actions_right,.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left{color:#fff;right:0em;position:absolute;opacity:0;transition:all 0.4s ease-in-out;z-index:1000}.cp.cpe1_old_apagar .dpt>.actions_right a.btn-bloco,.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left a.btn-bloco{background-color:#3498db;color:#ffffff !important;padding:8px 18px 6px;display:inline-block;line-height:1;float:right}.cp.cpe1_old_apagar .dpt>.actions_right a.btn-bloco:hover,.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left a.btn-bloco:hover{opacity:1;background-image:-webkit-linear-gradient(top, #1c81c4, #0b6dad);background-image:-moz-linear-gradient(top, #1c81c4, #0b6dad);background-image:-ms-linear-gradient(top, #1c81c4, #0b6dad);background-image:-o-linear-gradient(top, #1c81c4, #0b6dad);background-image:linear-gradient(to bottom, #1c81c4, #0b6dad)}.cp.cpe1_old_apagar .dpt:hover>.actions_right,.cp.cpe1_old_apagar .dpt-selected .csform .dpt:hover>.actions_left{opacity:1}.cp.cpe1_old_apagar .dpt .bloco{display:block;clear:both}.cp.cpe1_old_apagar .dpt .bloco *:hover{color:#27AE60}.cp.cpe1_old_apagar .dpt .bloco .de{cursor:pointer}.cp.cpe1_old_apagar .dpt .articulacao{border-top:2px solid #e5e5e5;margin:2em 0}.cp.cpe1_old_apagar .dpt .bloco_alteracao{margin:1em 0;padding:0em;background-color:transparent;min-height:100px;border:2px dashed #fff}.cp.cpe1_old_apagar .dpt .bloco_alteracao:hover{border-color:#d9ddde}.cp.cpe1_old_apagar .dpt .bloco_alteracao.drag{width:100% !important;border-color:#d9ddde}.cp.cpe1_old_apagar .dpt .bloco_alteracao.drag .dpt{transition-duration:0s !important}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt{width:100% !important;box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,0.12),0 2px 4px rgba(0,0,0,0.24);padding:0.3em 1em;margin:0;background-color:#edf0f1;z-index:1}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt:not(:first-child){border-top:1px solid white}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt.ui-draggable div{cursor:pointer}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt.dpt-comp-selected{transition:all 0.3s ease;width:auto !important;margin:2em -3.7em;box-shadow:0 0 6px rgba(0,0,0,0.16),0 6px 12px rgba(0,0,0,0.32)}.cp.cpe1_old_apagar .dpt-selected{font-size:1em;border:0px solid #CCC;margin:1em -1.8em 1em -1.8em;padding:2.2em 2.2em 1.6em 2.2em;box-shadow:-4px 15px 15px rgba(0,0,0,0.1),0px 6px 6px rgba(0,0,0,0.23);background-image:-webkit-linear-gradient(top, #eaeaee, #ddd);background-image:-moz-linear-gradient(top, #eaeaee, #ddd);background-image:-ms-linear-gradient(top, #eaeaee, #ddd);background-image:-o-linear-gradient(top, #eaeaee, #ddd);background-image:linear-gradient(to bottom, #eaeaee, #ddd)}.cp.cpe1_old_apagar .dpt-selected ul{list-style:none;margin:0;padding:0}.cp.cpe1_old_apagar .dpt-selected .semtexto{color:#999}.cp.cpe1_old_apagar .dpt-selected .bloco{opacity:0.5}.cp.cpe1_old_apagar .dpt-selected .bloco:hover{opacity:1}.cp.cpe1_old_apagar .dpt-selected .bloco a:hover{background:transparent}.cp.cpe1_old_apagar .dpt-selected>.bloco{opacity:1;margin:1em}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao{margin:0;padding:1em;border:0 transparent;background-image:-webkit-linear-gradient(top, #eaeaee, #ddd);background-image:-moz-linear-gradient(top, #eaeaee, #ddd);background-image:-ms-linear-gradient(top, #eaeaee, #ddd);background-image:-o-linear-gradient(top, #eaeaee, #ddd);background-image:linear-gradient(to bottom, #eaeaee, #ddd)}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao:hover{border-color:transparent}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao.drag{width:100% !important}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao.drag .dpt{transition-duration:0s !important}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao .dpt{width:auto !important;transition:all 0.3s ease;background-color:white}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao .dpt:not(:first-child){border-top:0px solid white}.cp.cpe1_old_apagar .dpt-selected>.dpt{padding:0}.cp.cpe1_old_apagar .dpt-selected>.dpt:last-child{padding-bottom:1em}.cp.cpe1_old_apagar .dpt-selected>.actions_right a.btn-bloco,.cp.cpe1_old_apagar .dpt-selected .csform .dpt-selected>.actions_left a.btn-bloco{display:none}.cp.cpe1_old_apagar .dpt-selected .csform{display:block;clear:both;z-index:9;position:static}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action{-webkit-animation:fadeIn 1s ease-in-out;-moz-animation:fadeIn 1s ease-in-out;-o-animation:fadeIn 1s ease-in-out;opacity:1;position:absolute;display:table;transition:all 0.4s ease-in-out}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action a{color:#16407c;display:block;background:transparent;vertical-align:middle;text-align:center;font-weight:normal;text-shadow:0 0 10px rgba(0,0,0,0.3);padding:0.33em 0.4em}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li{position:relative;display:table-cell;vertical-align:top}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li:hover{background-color:rgba(255,255,255,0.5)}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li:hover>a{text-shadow:0 0 5px #777;color:#0a5}.cp.cpe1_old_apagar .dpt-selected .csform .label_status{position:absolute;bottom:0;right:0;color:#889;padding:0.3em;font-size:80%;text-align:right;z-index:15;display:table}.cp.cpe1_old_apagar .dpt-selected .csform .label_status li{display:table-cell;padding:0 0.5em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents{z-index:11;top:0em;left:0em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents a{padding:0.62em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents div,.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents li{font-size:80%;display:table-cell;vertical-align:middle;border-right:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents div{padding:0 0.4em;font-stretch:condensed;font-variant:small-caps;font-weight:bold;text-shadow:0 0 10px #fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents>li:hover a{color:#16407c;font-weight:normal}.cp.cpe1_old_apagar .dpt-selected .csform .actions_top,.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom{top:0em;right:0em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_top a,.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom a{padding-right:1em;padding-left:1em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_top li,.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom li{display:table-cell;vertical-align:middle;border-left:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom{top:auto;left:0;bottom:0;display:inline-block;border-top:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom a{padding:0 0.4em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom li{border:0px;border-right:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_right,.cp.cpe1_old_apagar .dpt-selected .csform .actions_left{top:2.2em;right:0em;bottom:0;display:block}.cp.cpe1_old_apagar .dpt-selected .csform .actions_right li,.cp.cpe1_old_apagar .dpt-selected .csform .actions_left li{width:2.2em;display:block;border-bottom:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_right li:first-child,.cp.cpe1_old_apagar .dpt-selected .csform .actions_left li:first-child{border-top:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left{right:auto;left:0em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts{background:transparent;position:relative;z-index:19;display:table;width:100%}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li{display:table-cell}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li:hover>a{background-image:-webkit-linear-gradient(top, #1c81c4, #0b6dad);background-image:-moz-linear-gradient(top, #1c81c4, #0b6dad);background-image:-ms-linear-gradient(top, #1c81c4, #0b6dad);background-image:-o-linear-gradient(top, #1c81c4, #0b6dad);background-image:linear-gradient(to bottom, #1c81c4, #0b6dad)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a{background-image:-webkit-linear-gradient(top, #3498DB, #2980C9);background-image:-moz-linear-gradient(top, #3498DB, #2980C9);background-image:-ms-linear-gradient(top, #3498DB, #2980C9);background-image:-o-linear-gradient(top, #3498DB, #2980C9);background-image:linear-gradient(to bottom, #3498DB, #2980C9);border-right:1px solid #fff;padding:0.2em;display:block;color:white;text-align:center;white-space:nowrap}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar{text-align:left;background:#A70808;color:#c99;padding-left:1.7em;position:relative}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir:hover,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:hover{background-color:#c70808;color:#ecc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir::before,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before{z-index:20;position:absolute;background:url(/static/img/icon_delete_white.png) no-repeat 50% 50%;content:"";top:0;left:0;display:block;color:black;margin-left:0.4em;height:100%;width:2em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar{background:#1f8b4d;color:white}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:hover{background:#2d9c5c;color:white}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before{background:url(/static/img/icon_save_white.png) no-repeat 50% 50%}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a span{padding:0 0.7em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li:last-child>a{border-right:0px solid #fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li:nth-child(even) a{background:#3385CA}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li a{border-right:1px solid #fff;display:block;color:white;background:#2980C9;font-size:80%;padding:0.23em 1em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li a:hover{background:#0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior{table-layout:fixed}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul{transform:translateY(30px);transition:transform 0.1s linear, opacity 0.1s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;margin-left:0.5em;box-shadow:0px 6px 18px rgba(0,0,0,0.19),0px 2px 6px rgba(0,0,0,0.23);-webkit-transition-delay:0.4s;transition-delay:0.4s}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li a{border-right:0px !important}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child::before{border-width:0.375rem;border-style:inset inset solid;content:"";display:block;height:0px;width:0px;border-color:transparent transparent #3385CA;position:absolute;top:-0.71rem;left:0.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child:hover::before{border-color:transparent transparent #0A5EA4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul::after{content:"";position:absolute;z-index:-1;left:0;top:rem-calc(-25px);height:rem-calc(25px);width:100%;transition:all 0.3s cubic-bezier(0.55, 0, 0.1, 1)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior:hover>ul{transform:translateY(7px);transition:transform 0.4s linear, opacity 0.4s linear, clip 0s 0.2s;opacity:1;clip:rect(-100px, 2000px, 2000px, -100px)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir{display:block;position:static}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{transform:translateY(30px);transition:transform 0.1s linear, opacity 0.1s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;margin-left:0.5em;box-shadow:0px 6px 18px rgba(0,0,0,0.19),0px 2px 6px rgba(0,0,0,0.23);-webkit-transition-delay:0.4s;transition-delay:0.4s}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a{border-right:0px !important}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child::before{border-width:0.375rem;border-style:inset inset solid;content:"";display:block;height:0px;width:0px;border-color:transparent transparent #3385CA;position:absolute;top:-0.71rem;left:0.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:hover::before{border-color:transparent transparent #0A5EA4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul::after{content:"";position:absolute;z-index:-1;left:0;top:rem-calc(-25px);height:rem-calc(25px);width:100%;transition:all 0.3s cubic-bezier(0.55, 0, 0.1, 1)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir:hover>ul{transform:translateY(7px);transition:transform 0.4s linear, opacity 0.4s linear, clip 0s 0.2s;opacity:1;clip:rect(-100px, 2000px, 2000px, -100px)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{right:0.5em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a{background-color:#A70808}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a:hover{background:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child::before{border-color:transparent transparent #A70808;right:10%;left:auto}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:hover::before{border-color:transparent transparent #c70808}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo{z-index:2000}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul{transform:translateY(30px);transition:transform 0.1s linear, opacity 0.1s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;margin-left:0.5em;box-shadow:0px 6px 18px rgba(0,0,0,0.19),0px 2px 6px rgba(0,0,0,0.23);-webkit-transition-delay:0.4s;transition-delay:0.4s}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li a,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li a{border-right:0px !important}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li:first-child::before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li:first-child::before{border-width:0.375rem;border-style:inset inset solid;content:"";display:block;height:0px;width:0px;border-color:transparent transparent #3385CA;position:absolute;top:-0.71rem;left:0.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li:first-child:hover::before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li:first-child:hover::before{border-color:transparent transparent #0A5EA4}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul::after,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul::after{content:"";position:absolute;z-index:-1;left:0;top:rem-calc(-25px);height:rem-calc(25px);width:100%;transition:all 0.3s cubic-bezier(0.55, 0, 0.1, 1)}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li:hover>ul,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li:hover>ul{transform:translateY(7px);transition:transform 0.4s linear, opacity 0.4s linear, clip 0s 0.2s;opacity:1;clip:rect(-100px, 2000px, 2000px, -100px)}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li.menu_excluir>ul li:first-child::before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li.menu_excluir>ul li:first-child::before{right:auto;left:0.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform textarea{margin:0;resize:vertical;min-height:12.6em;border:0px;font-size:120%;width:100%}.cp.cpe1_old_apagar .dpt-selected .csform textarea:focus{background:#fff}.cp.cpe1_old_apagar .dpt-selected .csform textarea::-webkit-input-placeholder{color:#c70808;opacity:0.6;font-size:80%}.cp.cpe1_old_apagar .dpt-selected .csform textarea:-moz-placeholder{color:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform textarea::-moz-placeholder{color:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform textarea:-ms-input-placeholder{color:#c70808;opacity:0.6}.cp.cpe1_old_apagar .selected{background-color:rgba(255,255,255,0.5)}.cp.cpe1_old_apagar .selected a:hover{color:#16407c !important;font-weight:normal !important}.result-busca-dispositivo,.lista-dispositivo{padding:0 0 1em;min-height:3em}.result-busca-dispositivo ul,.lista-dispositivo ul{list-style:none;margin:0;padding:1em 0 0;transition:all 2s linear;clear:both}.result-busca-dispositivo ul li,.lista-dispositivo ul li{display:table;border-collapse:separate;border-bottom:1px solid white;width:100%}.result-busca-dispositivo ul li.ta_title,.lista-dispositivo ul li.ta_title{background-color:rgba(0,0,0,0.15);border-radius:4px 4px 0 0;width:100%}.result-busca-dispositivo ul li.ta_title span,.lista-dispositivo ul li.ta_title span{padding:0.5em}.result-busca-dispositivo ul li:last-child .itemlabel,.lista-dispositivo ul li:last-child .itemlabel{border-radius:0 0 4px 0px;margin:0px}.result-busca-dispositivo ul li:last-child .iteminput,.lista-dispositivo ul li:last-child .iteminput{border-radius:0 0 0px 4px}.result-busca-dispositivo ul li .iteminput,.lista-dispositivo ul li .iteminput{background-color:rgba(0,0,0,0.1);border-right:1px solid white;display:table-cell;padding:0.5em;vertical-align:middle;text-align:center}.result-busca-dispositivo ul li .iteminput input,.lista-dispositivo ul li .iteminput input{margin:0}.result-busca-dispositivo ul li .itemlabel,.lista-dispositivo ul li .itemlabel{background-color:rgba(0,0,0,0.1);display:table-cell;padding:0.5em;vertical-align:middle;width:100%}.result-busca-dispositivo ul li .itemlabel label,.lista-dispositivo ul li .itemlabel label{line-height:1;font-family:"SourceSansPro", Helvetica, Arial, sans-serif;display:block;margin:0px}.result-busca-dispositivo ul li .itemlabel .artigo,.lista-dispositivo ul li .itemlabel .artigo{float:none}.result-busca-dispositivo .nomenclatura_heranca,.lista-dispositivo .nomenclatura_heranca{font-size:90%;color:#057dba;display:inline}.cp-nav-parents>.dropdown-menu{left:0;right:auto}.cp-nav-parents>.dropdown-menu::before{content:'';position:absolute;top:-11px;width:100%;height:11px}.cp-nav-parents:hover>.dropdown-menu{display:block}.table-notificacoes tbody tr td{border-top:1px solid white;padding:5px;vertical-align:middle}.table-notificacoes tbody tr td ul{margin:0px}.table-notificacoes tbody tr td ul li:hover{background-color:rgba(0,0,0,0.1)}.btn-modal-open{float:right}.class_color_container{background:#ddd !important}.clear{clear:both}.mce-tinymce.mce-container{border:1px solid #ccc !important;margin-right:2px}.mce-btn button:hover{background-color:rgba(0,0,0,0.1) !important;text-shadow:0 0 5px #fff;box-shadow:0 0 5px #777}.mce-menu{background:#eee !important}.displaynone{display:none !important}@media only screen and (max-width: 800px){.cp .fixed{z-index:98;position:relative}.cp.cpe1 .dpt-selected{margin:1em 0}.cp.cpe1 .dpt-selected .csform .actions_parents,.cp.cpe1 .dpt-selected .csform .label_status{font-size:80%;position:static !important;display:block !important;padding:0em;height:auto !important;left:0;right:auto;text-align:left}.cp.cpe1 .dpt-selected .csform .actions_parents div,.cp.cpe1 .dpt-selected .csform .actions_parents li,.cp.cpe1 .dpt-selected .csform .label_status div,.cp.cpe1 .dpt-selected .csform .label_status li{display:inline-block !important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul{transform:translateY(30px);transition:transform 0.1s linear, opacity 0.1s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;margin-left:0.5em;box-shadow:0px 6px 18px rgba(0,0,0,0.19),0px 2px 6px rgba(0,0,0,0.23);-webkit-transition-delay:0.4s;transition-delay:0.4s}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li a{border-right:0px !important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li:first-child::before{border-width:0.375rem;border-style:inset inset solid;content:"";display:block;height:0px;width:0px;border-color:transparent transparent #3385CA;position:absolute;top:-0.71rem;left:0.9375rem}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li:first-child:hover::before{border-color:transparent transparent #0A5EA4}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul::after{content:"";position:absolute;z-index:-1;left:0;top:rem-calc(-25px);height:rem-calc(25px);width:100%;transition:all 0.3s cubic-bezier(0.55, 0, 0.1, 1)}.cp.cpe1 .dpt-selected .csform .actions_inserts>li:hover>ul{transform:translateY(7px);transition:transform 0.4s linear, opacity 0.4s linear, clip 0s 0.2s;opacity:1;clip:rect(-100px, 2000px, 2000px, -100px)}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a span{display:none}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-excluir,.cp.cpe1 .cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1_old_apagar .cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar{padding-left:0;min-width:1em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-excluir::before,.cp.cpe1 .cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before,.cp.cpe1_old_apagar .cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before{width:100%;margin:0}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in,.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_next,.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior{position:static}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in>ul{left:1em !important;right:1em !important;margin-left:0}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in>ul li:first-child::before{left:37%}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_next>ul{left:0 !important;right:1em !important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior>ul{left:1em !important;right:0 !important;margin-left:0;margin-right:0.5em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child::before{right:42%;left:auto}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{left:10% !important;right:0 !important;margin-left:0;margin-right:0.5em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child::before{right:0;left:auto}}@media print{.cp .vigencias,.toggle-topbar,.menu-icon,.button,.tipo-vigencias,.dne{display:none}#btn_font_menos,#btn_font_mais{display:none}.container{width:100%}} 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 diff --git a/start.sh b/start.sh new file mode 100755 index 000000000..226c70de4 --- /dev/null +++ b/start.sh @@ -0,0 +1,53 @@ +#!/bin/sh + + +create_env() { + # check if file exists + if [ -f "/var/interlegis/sapl/data/secret.key" ]; then + KEY=`cat /var/interlegis/sapl/data/secret.key` + else + KEY=`python3 genkey.py` + echo $KEY > data/secret.key + fi + + # TODO: rename env-test-bash to .env + FILENAME="/var/interlegis/sapl/sapl/.env" + + if [ -z "${DATABASE_URL:-}" ]; then + DATABASE_URL="postgresql://sapl:sapl@sapldb:5432/sapl" + fi + + # ALWAYS replace the content of .env variable + # If want to conditionally create only if absent then use IF below + # if [ ! -f $FILENAME ]; then + + touch $FILENAME + + + # explicitly use '>' to erase any previous content + echo "SECRET_KEY="$KEY > $FILENAME + # now only appends + echo "DATABASE_URL = "$DATABASE_URL >> $FILENAME + echo "DEBUG = ""${DEBUG-False}" >> $FILENAME + echo "EMAIL_USE_TLS = ""${USE_TLS-True}" >> $FILENAME + echo "EMAIL_PORT = ""${EMAIL_PORT-587}" >> $FILENAME + echo "EMAIL_HOST = ""${EMAIL_HOST-''}" >> $FILENAME + echo "EMAIL_HOST_USER = ""${EMAIL_HOST_USER-''}" >> $FILENAME + echo "EMAIL_HOST_PASSWORD = ""${EMAIL_HOST_PASSWORD-''}" >> $FILENAME +} + +echo "creating .env file..." +create_env +echo "done." + +# # python3 gen-env.py + +python3 manage.py bower install + +/bin/sh busy-wait.sh + +python3 manage.py migrate +python3 manage.py collectstatic --no-input +python3 manage.py rebuild_index --noinput + +/bin/sh gunicorn_start.sh From 2538e6da5c2b2e875d2996bb2592940f79ca4acd Mon Sep 17 00:00:00 2001 From: Luciano Henrique Nunes de Almeida Date: Thu, 20 Apr 2017 11:19:50 -0300 Subject: [PATCH 18/57] fix #832 - TipoVinculoNormaJuridica e NormaRelacionada (#1016) * Migra TipoVinculoNormaJuridica e arruma NormaRelacionada Signed-off-by: Luciano Almeida * Concerta alter sequence e assert no tipo vinculo da norma Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 56 +++++++++++++++++++++++++++++----------- sapl/norma/legacy.yaml | 8 +++--- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 8cfa25a4e..6ab3cd184 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -25,7 +25,7 @@ from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa, TipoMateriaLegislativa, TipoProposicao, Tramitacao) from sapl.norma.models import (AssuntoNorma, NormaJuridica, - TipoVinculoNormaJuridica) + TipoVinculoNormaJuridica, NormaRelacionada) from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia @@ -339,20 +339,34 @@ def get_fields_dict(model): def fill_vinculo_norma_juridica(): - lista = [('A', 'Altera a norma'), - ('R', 'Revoga integralmente a norma'), - ('P', 'Revoga parcialmente a norma'), - ('T', 'Revoga integralmente por consolidação'), - ('C', 'Norma Correlata'), - ('S', 'Ressalva a Norma'), - ('E', 'Reedita a Norma'), - ('I', 'Reedita a Norma com Alteração'), - ('G', 'Regulamenta a Norma'), - ('K', 'Suspende parcialmente a norma'), - ('L', 'Suspende integralmente a norma'), - ('N', 'Julgada integralmente inconstitucional'), - ('O', 'Julgada parcialmente inconstitucional')] - lista_objs = [TipoVinculoNormaJuridica(sigla=item[0], descricao=item[1]) + lista = [('A', 'Altera o(a)', + 'Alterado(a) pelo(a)'), + ('R', 'Revoga integralmente o(a)', + 'Revogado(a) integralmente pelo(a)'), + ('P', 'Revoga parcialmente o(a)', + 'Revogado(a) parcialmente pelo(a)'), + ('T', 'Revoga integralmente por consolidação', + 'Revogado(a) integralmente por consolidação'), + ('C', 'Norma correlata', + 'Norma correlata'), + ('S', 'Ressalva o(a)', + 'Ressalvada pelo(a)'), + ('E', 'Reedita o(a)', + 'Reeditada pelo(a)'), + ('I', 'Reedita com alteração o(a)', + 'Reeditada com alteração pelo(a)'), + ('G', 'Regulamenta o(a)', + 'Regulamentada pelo(a)'), + ('K', 'Suspende parcialmente o(a)', + 'Suspenso(a) parcialmente pelo(a)'), + ('L', 'Suspende integralmente o(a)', + 'Suspenso(a) integralmente pelo(a)'), + ('N', 'Julga integralmente inconstitucional', + 'Julgada integralmente inconstitucional'), + ('O', 'Julga parcialmente inconstitucional', + 'Julgada parcialmente inconstitucional')] + lista_objs = [TipoVinculoNormaJuridica( + sigla=item[0], descricao_ativa=item[1], descricao_passiva=item[2]) for item in lista] TipoVinculoNormaJuridica.objects.bulk_create(lista_objs) @@ -455,6 +469,7 @@ class DataMigrator: desconecta_sinais_indexacao() + fill_vinculo_norma_juridica() info('Começando migração: %s...' % obj) self._do_migrate(obj) @@ -543,6 +558,10 @@ class DataMigrator: if getattr(old, 'ind_excluido', False): self.to_delete.append(new) + # necessário para ajustar sequence da tabela para o ultimo valor de id + ultimo_valor = get_last_value(model) + alter_sequence(model, ultimo_valor+1) + def delete_ind_excluido(self): excluidos = 0 for obj in self.to_delete: @@ -619,6 +638,12 @@ def adjust_participacao(new, old): new.composicao = composicao +def adjust_normarelacionada(new, old): + tipo = TipoVinculoNormaJuridica.objects.filter(sigla=old.tip_vinculo) + assert len(tipo) == 1 + new.tipo_vinculo = tipo[0] + + def adjust_protocolo(new, old): if new.numero is None and not primeira_vez: p = ProtocoloLegado.objects.filter( @@ -724,6 +749,7 @@ AJUSTE_ANTES_SALVAR = { Autor: adjust_autor, Comissao: adjust_comissao, NormaJuridica: adjust_normajuridica_antes_salvar, + NormaRelacionada: adjust_normarelacionada, OrdemDia: adjust_ordemdia, Parlamentar: adjust_parlamentar, Participacao: adjust_participacao, diff --git a/sapl/norma/legacy.yaml b/sapl/norma/legacy.yaml index 17a7f083d..3294561b8 100644 --- a/sapl/norma/legacy.yaml +++ b/sapl/norma/legacy.yaml @@ -42,8 +42,6 @@ LegislacaoCitada: subsecao: des_subsecao titulo: des_titulo -# TODO Descomentar quando a issue #832 for concluida -# TipoVinculoNormaJuridica (VinculoNormaJuridica): -# norma_referente: cod_norma_referente -# norma_referida: cod_norma_referida -# tipo_vinculo: tip_vinculo +NormaRelacionada (VinculoNormaJuridica): + norma_principal: cod_norma_referente + norma_relacionada: cod_norma_referida From 66a529b783281d1a319d1ad0203d06593c0d920a Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 20 Apr 2017 11:26:50 -0300 Subject: [PATCH 19/57] =?UTF-8?q?HOT-FIX:=20permitir=20execu=C3=A7=C3=A3o?= =?UTF-8?q?=20do=20SAPL=20docker=20e=20standalone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gunicorn_start.sh | 9 +++++++++ start.sh | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gunicorn_start.sh b/gunicorn_start.sh index 9669644fa..5d82418df 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -23,6 +23,15 @@ DJANGO_WSGI_MODULE=sapl.wsgi # WSGI module name (*) echo "Starting $NAME as `whoami` on base dir $SAPL_DIR" +# parameter can be passed to run without virtualenv +if [[ "$@" != "no-venv" ]]; then + # Activate the virtual environment + cd $DJANGODIR + source /var/interlegis/.virtualenvs/sapl/bin/activate + export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE + export PYTHONPATH=$DJANGODIR:$PYTHONPATH +fi + # Create the run directory if it doesn't exist RUNDIR=$(dirname $SOCKFILE) test -d $RUNDIR || mkdir -p $RUNDIR diff --git a/start.sh b/start.sh index 226c70de4..0774b0e02 100755 --- a/start.sh +++ b/start.sh @@ -50,4 +50,4 @@ python3 manage.py migrate python3 manage.py collectstatic --no-input python3 manage.py rebuild_index --noinput -/bin/sh gunicorn_start.sh +/bin/sh gunicorn_start.sh no-venv From 38b6745b6ca906bfa399700dbe048df90c278e70 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 20 Apr 2017 15:18:11 -0300 Subject: [PATCH 20/57] Adiciona script para criar superuser --- create_admin.py | 33 +++++++++++++++++++++++++++++++++ start.sh | 20 +++++++++++++++++--- 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 create_admin.py diff --git a/create_admin.py b/create_admin.py new file mode 100644 index 000000000..d534c6696 --- /dev/null +++ b/create_admin.py @@ -0,0 +1,33 @@ +import sys +import os +import django + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sapl.settings") +django.setup() + +from django.contrib.auth.models import User + +def create_superuser(): + username = "admin" + password = os.environ['ADMIN_PASSWORD'] if 'ADMIN_PASSWORD' in os.environ else None + email = os.environ['ADMIN_EMAIL'] if 'ADMIN_EMAIL' in os.environ else '' + + if User.objects.filter(username=username).exists(): + # print("[SUPERUSER] User %s already exists. Exiting without change." % username) + sys.exit('ADMIN_USER_EXISTS') + else: + if not password: + # print("[SUPERUSER] Environment variable $ADMIN_PASSWORD for user %s was not set. Leaving..." % username) + sys.exit('MISSING_ADMIN_PASSWORD') + + print("[SUPERUSER] Creating superuser...") + + u = User.objects.create_superuser(username=username, password=password, email=email) + u.save() + + print("[SUPERUSER] Done.") + + sys.exit(0) + +if __name__ == '__main__': + create_superuser() diff --git a/start.sh b/start.sh index 0774b0e02..f421efa99 100755 --- a/start.sh +++ b/start.sh @@ -2,6 +2,7 @@ create_env() { + echo "[ENV FILE] creating .env file..." # check if file exists if [ -f "/var/interlegis/sapl/data/secret.key" ]; then KEY=`cat /var/interlegis/sapl/data/secret.key` @@ -10,7 +11,6 @@ create_env() { echo $KEY > data/secret.key fi - # TODO: rename env-test-bash to .env FILENAME="/var/interlegis/sapl/sapl/.env" if [ -z "${DATABASE_URL:-}" ]; then @@ -34,11 +34,11 @@ create_env() { echo "EMAIL_HOST = ""${EMAIL_HOST-''}" >> $FILENAME echo "EMAIL_HOST_USER = ""${EMAIL_HOST_USER-''}" >> $FILENAME echo "EMAIL_HOST_PASSWORD = ""${EMAIL_HOST_PASSWORD-''}" >> $FILENAME + + echo "[ENV FILE] done." } -echo "creating .env file..." create_env -echo "done." # # python3 gen-env.py @@ -50,4 +50,18 @@ python3 manage.py migrate python3 manage.py collectstatic --no-input python3 manage.py rebuild_index --noinput +user_created=$(python3 create_admin.py) + +echo $user_created + +#if [ $user_created -eq "ADMIN_USER_EXISTS" ]; then +# echo "[SUPERUSER CREATION] User admin already exists. Not creating" +#fi + +#if [ $user_created -eq "MISSING_ADMIN_PASSWORD" ]; then +# echo "[SUPERUSER] Environment variable $ADMIN_PASSWORD for superuser admin was not set. Leaving container" + # return -1 # TODO: Uncomment when in finally in prod. +#fi + + /bin/sh gunicorn_start.sh no-venv From ee1b73b9c8a297c40032e50e5921f3d2cbe1ba17 Mon Sep 17 00:00:00 2001 From: Matheus Veleci Date: Thu, 20 Apr 2017 11:30:40 -0300 Subject: [PATCH 21/57] =?UTF-8?q?Ajusta=20busy-wait=20para=20verificar=20a?= =?UTF-8?q?=20DATABASE=5FURL=20gen=C3=A9rica(Vari=C3=A1vel=20de=20Ambiente?= =?UTF-8?q?)=20e=20altera=20n=C3=BAmero=20de=20cores=20do=20gunicorn=5Fsta?= =?UTF-8?q?rt.sh=20para=209?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- busy-wait.sh | 2 +- gunicorn_start.sh | 2 +- start.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/busy-wait.sh b/busy-wait.sh index 128592ffc..73fde5c6b 100644 --- a/busy-wait.sh +++ b/busy-wait.sh @@ -1,7 +1,7 @@ #!/bin/sh while true; do - COUNT_PG=`psql --dbname=postgresql://sapl:sapl@sapldb/sapl -c '\l \q' | grep sapl | wc -l` + COUNT_PG=`psql $1 -c '\l \q' | grep sapl | wc -l` if ! [ "$COUNT_PG" -eq "0" ]; then break fi diff --git a/gunicorn_start.sh b/gunicorn_start.sh index 5d82418df..79666cf19 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -16,7 +16,7 @@ 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 (*) diff --git a/start.sh b/start.sh index f421efa99..893296a89 100755 --- a/start.sh +++ b/start.sh @@ -44,7 +44,7 @@ create_env python3 manage.py bower install -/bin/sh busy-wait.sh +/bin/sh busy-wait.sh $DATABASE_URL python3 manage.py migrate python3 manage.py collectstatic --no-input From c0ff18e4d8bd63085d7b6f8f1e5713f030567568 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 25 Apr 2017 11:22:43 -0300 Subject: [PATCH 22/57] Adiciona checagem de password e usuario admin existente --- create_admin.py | 4 ++-- start.sh | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/create_admin.py b/create_admin.py index d534c6696..7fe03a65c 100644 --- a/create_admin.py +++ b/create_admin.py @@ -13,11 +13,11 @@ def create_superuser(): email = os.environ['ADMIN_EMAIL'] if 'ADMIN_EMAIL' in os.environ else '' if User.objects.filter(username=username).exists(): - # print("[SUPERUSER] User %s already exists. Exiting without change." % username) + print("[SUPERUSER] User %s already exists. Exiting without change." % username) sys.exit('ADMIN_USER_EXISTS') else: if not password: - # print("[SUPERUSER] Environment variable $ADMIN_PASSWORD for user %s was not set. Leaving..." % username) + print("[SUPERUSER] Environment variable $ADMIN_PASSWORD for user %s was not set. Leaving..." % username) sys.exit('MISSING_ADMIN_PASSWORD') print("[SUPERUSER] Creating superuser...") diff --git a/start.sh b/start.sh index 893296a89..250be13ea 100755 --- a/start.sh +++ b/start.sh @@ -40,8 +40,6 @@ create_env() { create_env -# # python3 gen-env.py - python3 manage.py bower install /bin/sh busy-wait.sh $DATABASE_URL @@ -50,18 +48,22 @@ python3 manage.py migrate python3 manage.py collectstatic --no-input python3 manage.py rebuild_index --noinput -user_created=$(python3 create_admin.py) +user_created=$(python3 create_admin.py 2>&1) -echo $user_created +cmd=$(echo $user_created | grep 'ADMIN_USER_EXISTS') +user_exists=$? -#if [ $user_created -eq "ADMIN_USER_EXISTS" ]; then -# echo "[SUPERUSER CREATION] User admin already exists. Not creating" -#fi +cmd=$(echo $user_created | grep 'MISSING_ADMIN_PASSWORD') +lack_pwd=$? -#if [ $user_created -eq "MISSING_ADMIN_PASSWORD" ]; then -# echo "[SUPERUSER] Environment variable $ADMIN_PASSWORD for superuser admin was not set. Leaving container" - # return -1 # TODO: Uncomment when in finally in prod. -#fi +if [ $user_exists -eq 0 ]; then + echo "[SUPERUSER CREATION] User admin already exists. Not creating" +fi + +if [ $lack_pwd -eq 0 ]; then + echo "[SUPERUSER] Environment variable $ADMIN_PASSWORD for superuser admin was not set. Leaving container" + # return -1 +fi /bin/sh gunicorn_start.sh no-venv From 5ec8ad8d598504ed66fedf1a44b64475ea2b3590 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 25 Apr 2017 11:44:40 -0300 Subject: [PATCH 23/57] Closes #1031 --- sapl/templates/sessao/votacao/votacao_edit.html | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sapl/templates/sessao/votacao/votacao_edit.html b/sapl/templates/sessao/votacao/votacao_edit.html index 5c614ea00..753c49541 100644 --- a/sapl/templates/sessao/votacao/votacao_edit.html +++ b/sapl/templates/sessao/votacao/votacao_edit.html @@ -26,12 +26,10 @@
- Resultado da Votação: - {% for tipo in view.get_tipos_votacao %} - {% if votacao.tipo_resultado == tipo.id %} - {{ tipo.nome }} - {% endif %} - {% endfor %} +
+ Resultado da Votação: {{ votacao.resultado }} +
+
From 9e2db16563620288df9ead5086a6577155a0ebd1 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 25 Apr 2017 13:50:46 -0300 Subject: [PATCH 24/57] Closes 1037 --- .../templates/pdf_sessao_plenaria_gerar.py | 4 ++-- sapl/relatorios/views.py | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index 5917d0f8b..8890b9dcf 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -176,8 +176,8 @@ def expediente_materia(lst_expediente_materia): tmp += '\n' tmp += 'MatériaEmentaResultado da Votação\n' for expediente_materia in lst_expediente_materia: - tmp += '' + str(expediente_materia['num_ordem']) + ' - ' + expediente_materia['id_materia'] + '\n' + 'Turno: ' + expediente_materia[ - 'des_turno'] + '\n' + 'Autor: ' + expediente_materia['nom_autor'] + '\n' + tmp += '' + str(expediente_materia['num_ordem']) + ' - ' + expediente_materia['id_materia'] + '\n' + 'Turno: ' + str(expediente_materia[ + 'des_turno']) + '\n' + 'Autor: ' + str(expediente_materia['nom_autor']) + '\n' txt_ementa = expediente_materia['txt_ementa'].replace('&', '&') tmp += '' + txt_ementa + '\n' tmp += '' + \ diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 3a2ccd047..e09155bec 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -662,9 +662,9 @@ def get_sessao_plenaria(sessao, casa): materia=votacao.materia).first() if numeracao is not None: dic_votacao["des_numeracao"] = ( - str(numeracao.numero) + + str(numeracao.numero_materia) + '/' + - str(numeracao.ano)) + str(numeracao.ano_materia)) dic_votacao["des_turno"] = ' ' tramitacao = Tramitacao.objects.filter( @@ -1083,11 +1083,11 @@ def get_pauta_sessao(sessao, casa): dic_votacao["ordem_observacao"] = votacao.observacao dic_votacao["des_numeracao"] = ' ' - numeracao = Numeracao.objects.filter(materia=materia) - # if numeracao is not None: - # numeracao = numeracao.first() - # dic_votacao["des_numeracao"] = str( - # numeracao.numero) + '/' + str(numeracao.ano) +# numeracao = Numeracao.objects.filter(materia=materia) +# if numeracao is not None: +# numeracao = numeracao.first() +# dic_votacao["des_numeracao"] = str( +# numeracao.numero_materia) + '/' + str(numeracao.ano_materia) dic_votacao["nom_autor"] = ' ' autoria = Autoria.objects.filter( From df45d850074e7786ff79b8551007509cfcf6f4a2 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 25 Apr 2017 17:09:16 -0300 Subject: [PATCH 25/57] Fixes #1031 --- sapl/sessao/views.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 419ea4fa0..4367ec84d 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -164,8 +164,8 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): def get_rows(self, object_list): for obj in object_list: - resultados = obj.registrovotacao_set.all() - if not resultados: + exist_resultado = obj.registrovotacao_set.all().exists() + if not exist_resultado: if obj.votacao_aberta: url = '' if obj.tipo_votacao == 1: @@ -209,8 +209,11 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): else: obj.resultado = '''Não há resultado''' else: - resultado = resultados[0].tipo_resultado_votacao.nome - resultado_observacao = resultados[0].observacao + resultado = obj.registrovotacao_set.get( + materia_id=obj.materia_id) + resultado_descricao = resultado.tipo_resultado_votacao.nome + resultado_observacao = resultado.observacao + if self.request.user.has_module_perms(AppConfig.label): url = '' if obj.tipo_votacao == 1: @@ -233,11 +236,12 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): 'mid': obj.pk}) obj.resultado = ('%s
%s' % (url, - resultado, + resultado_descricao, resultado_observacao)) else: obj.resultado = ('%s
%s' % - (resultado, resultado_observacao)) + (resultado_descricao, + resultado_observacao)) return [self._as_row(obj) for obj in object_list] @@ -1057,7 +1061,7 @@ class ResumoView(DetailView): numero = o.numero_ordem # Verificar resultado - resultado = o.registrovotacao_set.all() + resultado = o.registrovotacao_set.filter(materia=o.materia) if resultado: resultado = resultado[0].tipo_resultado_votacao.nome else: @@ -1207,6 +1211,7 @@ class VotacaoEditView(SessaoPermissionMixin): ordem_id=ordem_id).last() votacao_existente = {'observacao': sub( ' ', ' ', strip_tags(votacao.observacao)), + 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': votacao.tipo_resultado_votacao_id} context.update({'votacao_titulo': titulo, @@ -1517,6 +1522,7 @@ class VotacaoNominalEditView(SessaoPermissionMixin): votacao_existente = {'observacao': sub( ' ', ' ', strip_tags(votacao.observacao)), + 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': votacao.tipo_resultado_votacao_id} context.update({'votacao': votacao_existente, @@ -1749,6 +1755,7 @@ class VotacaoNominalExpedienteEditView(SessaoPermissionMixin): votacao_existente = {'observacao': sub( ' ', ' ', strip_tags(votacao.observacao)), + 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': votacao.tipo_resultado_votacao_id} context.update({'votacao': votacao_existente, @@ -1983,6 +1990,7 @@ class VotacaoExpedienteEditView(SessaoPermissionMixin): expediente_id=expediente_id).last() votacao_existente = {'observacao': sub( ' ', ' ', strip_tags(votacao.observacao)), + 'resultado': votacao.tipo_resultado.nome, 'tipo_resultado': votacao.tipo_resultado_votacao_id} context.update({'votacao_titulo': titulo, From 6459c783698b9cc0ec6126527bbd5215817bd378 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 25 Apr 2017 17:26:32 -0300 Subject: [PATCH 26/57] Closes #1033 --- sapl/sessao/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 4367ec84d..02efb83d0 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -164,7 +164,9 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): def get_rows(self, object_list): for obj in object_list: - exist_resultado = obj.registrovotacao_set.all().exists() + exist_resultado = obj.registrovotacao_set.filter( + materia=obj.materia + ).exists() if not exist_resultado: if obj.votacao_aberta: url = '' From 1ac9fd690658216d1bad3a69a79c8fec8bb178de Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 26 Apr 2017 11:13:19 -0300 Subject: [PATCH 27/57] Closes #1032 --- sapl/sessao/forms.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index ded56d4cd..c4854e21f 100644 --- a/sapl/sessao/forms.py +++ b/sapl/sessao/forms.py @@ -83,11 +83,11 @@ class ExpedienteMateriaForm(ModelForm): def clean_numero_ordem(self): sessao = self.instance.sessao_plenaria - ex = ExpedienteMateria.objects.filter( + numero_ordem_exists = ExpedienteMateria.objects.filter( sessao_plenaria=sessao, - numero_ordem=self.cleaned_data['numero_ordem']).count() + numero_ordem=self.cleaned_data['numero_ordem']).exists() - if ex >= 1: + if numero_ordem_exists: msg = _('Esse número de ordem já existe.') raise ValidationError(msg) @@ -139,6 +139,22 @@ class OrdemDiaForm(ExpedienteMateriaForm): def clean_data_ordem(self): return self.instance.sessao_plenaria.data_inicio + + def clean_numero_ordem(self): + sessao = self.instance.sessao_plenaria + + numero_ordem_exists = OrdemDia.objects.filter( + sessao_plenaria=sessao, + numero_ordem=self.cleaned_data[ + 'numero_ordem']).exists() + + if exists_numero_ordem: + msg = _('Esse número de ordem já existe.') + raise ValidationError(msg) + + return self.cleaned_data['numero_ordem'] + + def clean(self): cleaned_data = self.cleaned_data sessao = self.instance.sessao_plenaria From 62480af20a6ff34e1ff0d720431fc88da189dc79 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 26 Apr 2017 11:26:35 -0300 Subject: [PATCH 28/57] =?UTF-8?q?HOT-FIX:=20vari=C3=A1vel=20com=20nome=20e?= =?UTF-8?q?rrado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index c4854e21f..4303dabcc 100644 --- a/sapl/sessao/forms.py +++ b/sapl/sessao/forms.py @@ -148,7 +148,7 @@ class OrdemDiaForm(ExpedienteMateriaForm): numero_ordem=self.cleaned_data[ 'numero_ordem']).exists() - if exists_numero_ordem: + if numero_ordem_exists: msg = _('Esse número de ordem já existe.') raise ValidationError(msg) From 382d6bd376d88d6b227337625c217a508cfe1a3a Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 26 Apr 2017 15:53:56 -0300 Subject: [PATCH 29/57] Closes #1009 --- sapl/relatorios/views.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index e09155bec..62edc9791 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -520,10 +520,18 @@ def get_sessao_plenaria(sessao, casa): lst_expedientes = [] expedientes = ExpedienteSessao.objects.filter( sessao_plenaria=sessao).order_by('tipo__nome') + for e in expedientes: + dic_expedientes = {} dic_expedientes["nom_expediente"] = e.tipo.nome - dic_expedientes["txt_expediente"] = e.conteudo + conteudo = e.conteudo + # escape special character '&' + # https://github.com/interlegis/sapl/issues/1009 + conteudo = conteudo.replace('&', '&') + + dic_expedientes["txt_expediente"] = conteudo + if dic_expedientes: lst_expedientes.append(dic_expedientes) From 702086d12fa76b936b7f8ee797820d762e12f6ea Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 26 Apr 2017 17:13:01 -0300 Subject: [PATCH 30/57] Fixes #1046 --- sapl/relatorios/views.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 62edc9791..4b5416c2c 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -1,5 +1,8 @@ from datetime import datetime +import re +import html + from django.core.exceptions import ObjectDoesNotExist from django.http import Http404, HttpResponse from django.utils.translation import ugettext_lazy as _ @@ -526,6 +529,12 @@ def get_sessao_plenaria(sessao, casa): dic_expedientes = {} dic_expedientes["nom_expediente"] = e.tipo.nome conteudo = e.conteudo + + # unescape HTML codes + # https://github.com/interlegis/sapl/issues/1046 + conteudo = re.sub('style=".*?"', '', conteudo) + conteudo = html.unescape(conteudo) + # escape special character '&' # https://github.com/interlegis/sapl/issues/1009 conteudo = conteudo.replace('&', '&') From 7a2a90f51672747eb77ecf4af844ed80d24ca5c7 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 27 Apr 2017 09:36:04 -0300 Subject: [PATCH 31/57] =?UTF-8?q?HOT-FIX:=20solu=C3=A7=C3=A3o=20parcial=20?= =?UTF-8?q?para=20issue=20#1049?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/views.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 02efb83d0..0aa143590 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -280,8 +280,10 @@ class ExpedienteMateriaCrud(MasterDetailCrud): def get_rows(self, object_list): for obj in object_list: - resultados = obj.registrovotacao_set.all() - if not resultados: + exist_resultado = obj.registrovotacao_set.filter( + materia=obj.materia + ).exists() + if not exist_resultado: if obj.votacao_aberta: url = '' if obj.tipo_votacao == 1: @@ -323,7 +325,10 @@ class ExpedienteMateriaCrud(MasterDetailCrud): obj.resultado = btn_abrir else: url = '' - resultado = resultados[0].tipo_resultado_votacao.nome + resultado = obj.registrovotacao_set.get( + materia_id=obj.materia_id) + resultado_descricao = resultado.tipo_resultado_votacao.nome + resultado_observacao = resultado.observacao if self.request.user.has_module_perms(AppConfig.label): if obj.tipo_votacao == 1: url = reverse( @@ -344,10 +349,14 @@ class ExpedienteMateriaCrud(MasterDetailCrud): 'pk': obj.sessao_plenaria_id, 'oid': obj.materia_id, 'mid': obj.pk}) - obj.resultado = '%s' % (url, - resultado) + obj.resultado = ('%s
%s' % + (url, + resultado_descricao, + resultado_observacao)) else: - obj.resultado = '%s' % (resultado) + obj.resultado = ('%s
%s' % + (resultado_descricao, + resultado_observacao)) return [self._as_row(obj) for obj in object_list] class CreateView(MasterDetailCrud.CreateView): From 7c3b2a278fb896722a5104ddb56cc4a1b2a6943c Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 27 Apr 2017 09:46:06 -0300 Subject: [PATCH 32/57] Fixes #1043 --- sapl/templates/sessao/resumo.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sapl/templates/sessao/resumo.html b/sapl/templates/sessao/resumo.html index 2dcb586d9..ad1771305 100644 --- a/sapl/templates/sessao/resumo.html +++ b/sapl/templates/sessao/resumo.html @@ -112,8 +112,9 @@
{% for o in oradores %} -
{{o.numero_ordem}} - {{o.parlamentar}}
-
{{o.url_discurso}}
+
{{o.numero_ordem}} - {{o.parlamentar}}
+
{{o.url_discurso}}
+
{% endfor %}
From 62e7e0b370ec74a10eba29e8b90f7f3617cb47eb Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 27 Apr 2017 10:49:58 -0300 Subject: [PATCH 33/57] Closes #1042 --- sapl/env-backup | 8 ++++++++ sapl/sessao/views.py | 20 +++++++++++++++++++- sapl/templates/sessao/resumo.html | 16 ++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 sapl/env-backup diff --git a/sapl/env-backup b/sapl/env-backup new file mode 100644 index 000000000..5824d3eec --- /dev/null +++ b/sapl/env-backup @@ -0,0 +1,8 @@ +SECRET_KEY=qbl0+_+h6^u_k0ggkv&+ff&56s!d(*k+vk^_eu3-to_w&k-kp@ +DATABASE_URL = postgresql://sapl:sapl@localhost:5432/sapl +DEBUG = True +EMAIL_USE_TLS = True +EMAIL_PORT = 587 +EMAIL_HOST = '' +EMAIL_HOST_USER = '' +EMAIL_HOST_PASSWORD = '' diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 0aa143590..85c041115 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -28,7 +28,7 @@ from sapl.materia.models import (Autoria, DocumentoAcessorio, TipoMateriaLegislativa, Tramitacao) from sapl.materia.views import MateriaLegislativaPesquisaView from sapl.norma.models import NormaJuridica -from sapl.parlamentares.models import (Legislatura, Parlamentar, +from sapl.parlamentares.models import (Filiacao, Legislatura, Parlamentar, SessaoLegislativa) from sapl.sessao.apps import AppConfig from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm @@ -1092,6 +1092,24 @@ class ResumoView(DetailView): context.update({'materias_ordem': materias_ordem}) + # ===================================================================== + # Oradores nas Explicações Pessoais + oradores_explicacoes = [] + for orador in Orador.objects.filter(sessao_plenaria_id=self.object.id): + for parlamentar in Parlamentar.objects.filter( + id=orador.parlamentar.id): + partido_sigla = Filiacao.objects.filter( + parlamentar=parlamentar).first().partido.sigla + if not partido_sigla: + partido_sigla = '' + oradores = { + 'numero_ordem': orador.numero_ordem, + 'parlamentar': parlamentar.nome_parlamentar, + 'sgl_partido': partido_sigla + } + oradores_explicacoes.append(oradores) + context.update({'oradores_explicacoes': oradores_explicacoes}) + return self.render_to_response(context) diff --git a/sapl/templates/sessao/resumo.html b/sapl/templates/sessao/resumo.html index ad1771305..059fe5346 100644 --- a/sapl/templates/sessao/resumo.html +++ b/sapl/templates/sessao/resumo.html @@ -155,4 +155,20 @@ + +
+ Oradores das Explicações Pessoais +
+
Parlamentar
+
Discurso
+
+
+ {% for o in oradores_explicacoes %} +
{{o.numero_ordem}} - {{o.parlamentar}}
+
{{o.url_discurso}}
+
+ {% endfor %} +
+
+ {% endblock detail_content %} From 69b5a38e3426be7cd946d7268b80b1970956abc1 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 27 Apr 2017 10:53:33 -0300 Subject: [PATCH 34/57] Closes #1039 --- sapl/templates/sessao/presenca.html | 4 ++-- sapl/templates/sessao/presenca_ordemdia.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sapl/templates/sessao/presenca.html b/sapl/templates/sessao/presenca.html index bbdb934a4..3d24f429e 100644 --- a/sapl/templates/sessao/presenca.html +++ b/sapl/templates/sessao/presenca.html @@ -23,7 +23,7 @@
{% endfor %} @@ -42,7 +42,7 @@ {% for parlamentar, check in view.get_presencas %} {% if check %}
-
+
{% endif %} {% endfor %} diff --git a/sapl/templates/sessao/presenca_ordemdia.html b/sapl/templates/sessao/presenca_ordemdia.html index 1b66b53b1..63800f196 100644 --- a/sapl/templates/sessao/presenca_ordemdia.html +++ b/sapl/templates/sessao/presenca_ordemdia.html @@ -24,7 +24,7 @@
{% endfor %} @@ -44,7 +44,7 @@ {% for parlamentar, check in view.get_presencas_ordem %} {% if check %}
-
+
{% endif %} {% endfor %} From d599dbd2a90c8df8ac49e55629348f841e95d262 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 27 Apr 2017 11:12:43 -0300 Subject: [PATCH 35/57] Fixes #1041 --- sapl/sessao/views.py | 4 ++-- sapl/templates/sessao/presenca.html | 4 ++-- sapl/templates/sessao/presenca_ordemdia.html | 4 ++-- sapl/templates/sessao/resumo.html | 9 +++++---- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 85c041115..3bcba074e 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -1099,12 +1099,12 @@ class ResumoView(DetailView): for parlamentar in Parlamentar.objects.filter( id=orador.parlamentar.id): partido_sigla = Filiacao.objects.filter( - parlamentar=parlamentar).first().partido.sigla + parlamentar=parlamentar).last().partido.sigla if not partido_sigla: partido_sigla = '' oradores = { 'numero_ordem': orador.numero_ordem, - 'parlamentar': parlamentar.nome_parlamentar, + 'parlamentar': parlamentar, 'sgl_partido': partido_sigla } oradores_explicacoes.append(oradores) diff --git a/sapl/templates/sessao/presenca.html b/sapl/templates/sessao/presenca.html index 3d24f429e..7317cde38 100644 --- a/sapl/templates/sessao/presenca.html +++ b/sapl/templates/sessao/presenca.html @@ -23,7 +23,7 @@
{% endfor %} @@ -42,7 +42,7 @@ {% for parlamentar, check in view.get_presencas %} {% if check %}
-
+
{% endif %} {% endfor %} diff --git a/sapl/templates/sessao/presenca_ordemdia.html b/sapl/templates/sessao/presenca_ordemdia.html index 63800f196..7f9f0487b 100644 --- a/sapl/templates/sessao/presenca_ordemdia.html +++ b/sapl/templates/sessao/presenca_ordemdia.html @@ -24,7 +24,7 @@
{% endfor %} @@ -44,7 +44,7 @@ {% for parlamentar, check in view.get_presencas_ordem %} {% if check %}
-
+
{% endif %} {% endfor %} diff --git a/sapl/templates/sessao/resumo.html b/sapl/templates/sessao/resumo.html index 059fe5346..e338f322c 100644 --- a/sapl/templates/sessao/resumo.html +++ b/sapl/templates/sessao/resumo.html @@ -42,7 +42,8 @@ Mesa Diretora
{% for m in mesa %} -
{{m.cargo}}: {{m.parlamentar.nome_parlamentar}}
+
{{m.cargo}}: + {{m.parlamentar.nome_parlamentar}} / {{ m.parlamentar.filiacao_set.last.partido.sigla }}
{% endfor %}
@@ -52,7 +53,7 @@ Lista de Presença na Sessão
{% for p in presenca_sessao %} -
{{p}}
+
{{p.nome_parlamentar}} / {{ p.filiacao_set.last.partido.sigla }}
{% endfor %}
@@ -124,7 +125,7 @@ Lista de Presença na Ordem do Dia
{% for p in presenca_ordem %} -
{{p}}
+
{{p.nome_parlamentar}} / {{ p.filiacao_set.last.partido.sigla }}
{% endfor %}
@@ -164,7 +165,7 @@
{% for o in oradores_explicacoes %} -
{{o.numero_ordem}} - {{o.parlamentar}}
+
{{o.numero_ordem}} - {{o.parlamentar.nome_parlamentar}} / {{ o.parlamentar.filiacao_set.last.partido.sigla }}
{{o.url_discurso}}

{% endfor %} From 0ee13a878cf341e113105430aec023fa365d85fc Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 27 Apr 2017 11:27:45 -0300 Subject: [PATCH 36/57] Fixes #1041: troca filiacao_set.last por parlamentar.filiacao_atual --- sapl/templates/sessao/presenca.html | 4 ++-- sapl/templates/sessao/presenca_ordemdia.html | 4 ++-- sapl/templates/sessao/resumo.html | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sapl/templates/sessao/presenca.html b/sapl/templates/sessao/presenca.html index 7317cde38..372bc8c88 100644 --- a/sapl/templates/sessao/presenca.html +++ b/sapl/templates/sessao/presenca.html @@ -23,7 +23,7 @@
{% endfor %} @@ -42,7 +42,7 @@ {% for parlamentar, check in view.get_presencas %} {% if check %}
-
+
{% endif %} {% endfor %} diff --git a/sapl/templates/sessao/presenca_ordemdia.html b/sapl/templates/sessao/presenca_ordemdia.html index 7f9f0487b..edb4055ca 100644 --- a/sapl/templates/sessao/presenca_ordemdia.html +++ b/sapl/templates/sessao/presenca_ordemdia.html @@ -24,7 +24,7 @@
{% endfor %} @@ -44,7 +44,7 @@ {% for parlamentar, check in view.get_presencas_ordem %} {% if check %}
-
+
{% endif %} {% endfor %} diff --git a/sapl/templates/sessao/resumo.html b/sapl/templates/sessao/resumo.html index e338f322c..37554992a 100644 --- a/sapl/templates/sessao/resumo.html +++ b/sapl/templates/sessao/resumo.html @@ -43,7 +43,7 @@
{% for m in mesa %}
{{m.cargo}}: - {{m.parlamentar.nome_parlamentar}} / {{ m.parlamentar.filiacao_set.last.partido.sigla }}
+
{{m.parlamentar.nome_parlamentar}} / {{ m.parlamentar.filiacao_atual }}
{% endfor %}
@@ -53,7 +53,7 @@ Lista de Presença na Sessão
{% for p in presenca_sessao %} -
{{p.nome_parlamentar}} / {{ p.filiacao_set.last.partido.sigla }}
+
{{p.nome_parlamentar}} / {{ p.filiacao_atual }}
{% endfor %}
@@ -125,7 +125,7 @@ Lista de Presença na Ordem do Dia
{% for p in presenca_ordem %} -
{{p.nome_parlamentar}} / {{ p.filiacao_set.last.partido.sigla }}
+
{{p.nome_parlamentar}} / {{ p.filiacao_atual }}
{% endfor %}
@@ -165,7 +165,7 @@
{% for o in oradores_explicacoes %} -
{{o.numero_ordem}} - {{o.parlamentar.nome_parlamentar}} / {{ o.parlamentar.filiacao_set.last.partido.sigla }}
+
{{o.numero_ordem}} - {{o.parlamentar.nome_parlamentar}} / {{ o.parlamentar.filiacao_atual }}
{{o.url_discurso}}

{% endfor %} From a6fb0c2873f92dc9aa2d30d6be2abeac0b264e0b Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 27 Apr 2017 11:51:32 -0300 Subject: [PATCH 37/57] Fixes #1050 --- sapl/templates/base/RelatorioPresencaSessao_filter.html | 2 +- sapl/templates/parlamentares/parlamentar_perfil_publico.html | 2 +- sapl/templates/parlamentares/public_composicaomesa_form.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sapl/templates/base/RelatorioPresencaSessao_filter.html b/sapl/templates/base/RelatorioPresencaSessao_filter.html index 8aeae7aa6..c9c92328b 100644 --- a/sapl/templates/base/RelatorioPresencaSessao_filter.html +++ b/sapl/templates/base/RelatorioPresencaSessao_filter.html @@ -37,7 +37,7 @@ {% for p in parlamentares %} - {{p}} / {{p.filiacao_set.first.partido.sigla|default:"Sem Partido"}} + {{p}} / {{p.filiacao_atual|default:"Sem Partido"}} {{p.sessao_count}} {{p.sessao_porc}} {{p.ordemdia_count}} diff --git a/sapl/templates/parlamentares/parlamentar_perfil_publico.html b/sapl/templates/parlamentares/parlamentar_perfil_publico.html index 11bfc6bfc..1c5ead0fc 100644 --- a/sapl/templates/parlamentares/parlamentar_perfil_publico.html +++ b/sapl/templates/parlamentares/parlamentar_perfil_publico.html @@ -31,7 +31,7 @@
-

Partido:   {{object.filiacao_set.first.partido|default_if_none:"Não informado"}}

+

Partido:   {{object.filiacao_atual|default_if_none:"Não informado"}}

diff --git a/sapl/templates/parlamentares/public_composicaomesa_form.html b/sapl/templates/parlamentares/public_composicaomesa_form.html index 15c62ab28..fbd780a30 100644 --- a/sapl/templates/parlamentares/public_composicaomesa_form.html +++ b/sapl/templates/parlamentares/public_composicaomesa_form.html @@ -51,7 +51,7 @@ {% endif %} {{p.parlamentar.nome_parlamentar}} - {{p.parlamentar.filiacao_set.last.partido.sigla}} + {{p.parlamentar.filiacao_atual}} {{p.cargo}} {% endfor %} From c5e609102800449a06d7a87ba14a2ee4d555bffa Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 27 Apr 2017 17:10:03 -0300 Subject: [PATCH 38/57] Fixes #1057 --- sapl/templates/protocoloadm/protocolo_mostrar.html | 1 + 1 file changed, 1 insertion(+) diff --git a/sapl/templates/protocoloadm/protocolo_mostrar.html b/sapl/templates/protocoloadm/protocolo_mostrar.html index 94d604461..49dba8a90 100644 --- a/sapl/templates/protocoloadm/protocolo_mostrar.html +++ b/sapl/templates/protocoloadm/protocolo_mostrar.html @@ -6,6 +6,7 @@ Protocolo: {{ protocolo.numero|stringformat:'06d' }}/{{ protocolo.ano }}
Assunto: {{ protocolo.assunto_ementa|default:" Não informado." }}
Data Protocolo: {{ protocolo.data|date:"d/m/Y" }} - Horário: {{ protocolo.hora|date:"H:i" }}
+ Autor: {{protocolo.autor.nome}}
Interessado: {{ protocolo.interessado|default:" Não informado." }}
Natureza do Processo: {% if protocolo.tipo_processo == 0 %} Administrativo {% elif protocolo.tipo_processo == 1 %} Legislativo {% endif %}
From 38768a62c48c360e942706b66a7eac23f7dba718 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 28 Apr 2017 09:22:18 -0300 Subject: [PATCH 39/57] Fixes #1055 --- sapl/materia/models.py | 17 +++++++++++++++++ .../materia/materialegislativa_filter.html | 11 ++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 1a9d2afff..cf8e53d8b 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -4,6 +4,7 @@ import reversion from django.contrib.auth.models import Group from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.models import ContentType +from django.core.exceptions import ObjectDoesNotExist from django.db import models from django.utils import formats from django.utils.translation import ugettext_lazy as _ @@ -215,6 +216,22 @@ class MateriaLegislativa(models.Model): return _('%(tipo)s nº %(numero)s de %(ano)s') % { 'tipo': self.tipo, 'numero': self.numero, 'ano': self.ano} + def data_entrada_protocolo(self): + ''' + hack: recuperar a data de entrada do protocolo sem gerar + dependência circular + ''' + from sapl.protocoloadm.models import Protocolo + if self.ano and self.numero_protocolo: + try: + return Protocolo.objects.get( + ano=self.ano, + numero=self.numero_protocolo).data + except ObjectDoesNotExist: + pass + + return '' + def delete(self, using=None, keep_parents=False): if self.texto_original: self.texto_original.delete() diff --git a/sapl/templates/materia/materialegislativa_filter.html b/sapl/templates/materia/materialegislativa_filter.html index cd459c61c..4af743b7b 100644 --- a/sapl/templates/materia/materialegislativa_filter.html +++ b/sapl/templates/materia/materialegislativa_filter.html @@ -47,6 +47,14 @@ Apresentação: {{ m.data_apresentacao }}
{% endif %} + {% if m.numeracao_set.first %} + Processo: {{ m.numeracao_set.first.numero_materia }} / {{ m.numeracao_set.first.ano_materia }} +
+ {% endif %} + {% if m.numero_protocolo %} + Protocolo: {{m.numero_protocolo}}/{{m.ano}}    Data Entrada: {{m.data_entrada_protocolo}}
+ + {% endif %} {% if m.autoria_set.all %} Autores: {% for a in m.autoria_set.all %} @@ -57,7 +65,7 @@ {% endif %} {% endfor %}
- {% endif %} + {% endif %} {% if m.tramitacao_set.last.unidade_tramitacao_destino %} Localização Atual:  {{m.tramitacao_set.last.unidade_tramitacao_destino}}
{% endif %} @@ -79,6 +87,7 @@ {% endif %} {% if m.tramitacao_set.last.data_tramitacao %} Data da última Tramitação:  {{m.tramitacao_set.last.data_tramitacao}}
+ Ultima Ação:   {{m.tramitacao_set.last.texto}}
{% endif %} {% if m.anexo_de.exists %} {% for a in m.materia_anexada_set.all %} From c7e55e18b38ae72a5c374a881a1f91686377bd8c Mon Sep 17 00:00:00 2001 From: Matheus Veleci Date: Tue, 2 May 2017 14:54:50 -0300 Subject: [PATCH 40/57] Executa rebuild index em backgroud --- start.sh | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/start.sh b/start.sh index 250be13ea..94a0392e3 100755 --- a/start.sh +++ b/start.sh @@ -2,7 +2,6 @@ create_env() { - echo "[ENV FILE] creating .env file..." # check if file exists if [ -f "/var/interlegis/sapl/data/secret.key" ]; then KEY=`cat /var/interlegis/sapl/data/secret.key` @@ -11,6 +10,7 @@ create_env() { echo $KEY > data/secret.key fi + # TODO: rename env-test-bash to .env FILENAME="/var/interlegis/sapl/sapl/.env" if [ -z "${DATABASE_URL:-}" ]; then @@ -34,11 +34,13 @@ create_env() { echo "EMAIL_HOST = ""${EMAIL_HOST-''}" >> $FILENAME echo "EMAIL_HOST_USER = ""${EMAIL_HOST_USER-''}" >> $FILENAME echo "EMAIL_HOST_PASSWORD = ""${EMAIL_HOST_PASSWORD-''}" >> $FILENAME - - echo "[ENV FILE] done." } +echo "creating .env file..." create_env +echo "done." + +# # python3 gen-env.py python3 manage.py bower install @@ -46,24 +48,6 @@ python3 manage.py bower install python3 manage.py migrate python3 manage.py collectstatic --no-input -python3 manage.py rebuild_index --noinput - -user_created=$(python3 create_admin.py 2>&1) - -cmd=$(echo $user_created | grep 'ADMIN_USER_EXISTS') -user_exists=$? - -cmd=$(echo $user_created | grep 'MISSING_ADMIN_PASSWORD') -lack_pwd=$? - -if [ $user_exists -eq 0 ]; then - echo "[SUPERUSER CREATION] User admin already exists. Not creating" -fi - -if [ $lack_pwd -eq 0 ]; then - echo "[SUPERUSER] Environment variable $ADMIN_PASSWORD for superuser admin was not set. Leaving container" - # return -1 -fi - +python3 manage.py rebuild_index --noinput & -/bin/sh gunicorn_start.sh no-venv +/bin/sh gunicorn_start.sh From e3660b0047e9c332e52422c34401d2b6d6189984 Mon Sep 17 00:00:00 2001 From: Matheus Veleci Date: Tue, 2 May 2017 14:58:11 -0300 Subject: [PATCH 41/57] =?UTF-8?q?Executa=20rebuild=20index=20em=20backgrou?= =?UTF-8?q?d=20-=20Ajusta=20start.sh=20do=20=C3=BAltimo=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- start.sh | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/start.sh b/start.sh index 94a0392e3..26a7e869b 100755 --- a/start.sh +++ b/start.sh @@ -1,7 +1,5 @@ -#!/bin/sh - - create_env() { + echo "[ENV FILE] creating .env file..." # check if file exists if [ -f "/var/interlegis/sapl/data/secret.key" ]; then KEY=`cat /var/interlegis/sapl/data/secret.key` @@ -10,7 +8,6 @@ create_env() { echo $KEY > data/secret.key fi - # TODO: rename env-test-bash to .env FILENAME="/var/interlegis/sapl/sapl/.env" if [ -z "${DATABASE_URL:-}" ]; then @@ -34,13 +31,11 @@ create_env() { echo "EMAIL_HOST = ""${EMAIL_HOST-''}" >> $FILENAME echo "EMAIL_HOST_USER = ""${EMAIL_HOST_USER-''}" >> $FILENAME echo "EMAIL_HOST_PASSWORD = ""${EMAIL_HOST_PASSWORD-''}" >> $FILENAME + + echo "[ENV FILE] done." } -echo "creating .env file..." create_env -echo "done." - -# # python3 gen-env.py python3 manage.py bower install @@ -50,4 +45,22 @@ python3 manage.py migrate python3 manage.py collectstatic --no-input python3 manage.py rebuild_index --noinput & -/bin/sh gunicorn_start.sh +user_created=$(python3 create_admin.py 2>&1) + +cmd=$(echo $user_created | grep 'ADMIN_USER_EXISTS') +user_exists=$? + +cmd=$(echo $user_created | grep 'MISSING_ADMIN_PASSWORD') +lack_pwd=$? + +if [ $user_exists -eq 0 ]; then + echo "[SUPERUSER CREATION] User admin already exists. Not creating" +fi + +if [ $lack_pwd -eq 0 ]; then + echo "[SUPERUSER] Environment variable $ADMIN_PASSWORD for superuser admin was not set. Leaving container" + # return -1 +fi + + +/bin/sh gunicorn_start.sh no-venv From f259f5e84968b858a9195d1cb395795e3646ff1a Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 2 May 2017 17:17:10 -0300 Subject: [PATCH 42/57] Fix #1060 --- sapl/materia/models.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sapl/materia/models.py b/sapl/materia/models.py index cf8e53d8b..b5390f3b4 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -685,9 +685,19 @@ class Proposicao(models.Model): ) def __str__(self): - return '%s %s/%s' % (Proposicao._meta.verbose_name, - self.numero_proposicao, - self.ano) + if self.ano and self.numero_proposicao: + return '%s %s/%s' % (Proposicao._meta.verbose_name, + self.numero_proposicao, + self.ano) + else: + if len(self.descricao) < 30: + descricao = self.descricao[:28] + ' ...' + else: + descricao = self.descricao + + return '%s %s/%s' % (Proposicao._meta.verbose_name, + self.id, + descricao) def delete(self, using=None, keep_parents=False): if self.texto_original: From dbaae51466c7c0b572a7048977b27e85deb64b36 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 2 May 2017 18:04:45 -0300 Subject: [PATCH 43/57] Fix #1051 --- sapl/parlamentares/models.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index d09f8dfac..4d15ab6fd 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -85,7 +85,8 @@ class Coligacao(models.Model): verbose_name=_('Legislatura')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) numero_votos = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Nº Votos Recebidos')) + blank=True, null=True, + verbose_name=_('Nº Votos Recebidos (Coligação)')) class Meta: verbose_name = _('Coligação') @@ -448,7 +449,7 @@ class Mandato(models.Model): tipo_causa_fim_mandato = models.PositiveIntegerField(blank=True, null=True) data_fim_mandato = models.DateField(verbose_name=_('Fim do Mandato')) votos_recebidos = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Votos Recebidos')) + blank=True, null=True, verbose_name=_('Votos Recebidos (Mandato)')) data_expedicao_diploma = models.DateField( verbose_name=_('Expedição do Diploma')) titular = models.BooleanField( From ba8bc9ea7588be9d9c88f9fd3401778a96dab50b Mon Sep 17 00:00:00 2001 From: Fabio Rauber Date: Wed, 3 May 2017 13:59:07 -0300 Subject: [PATCH 44/57] Nginx is now part of SAPL container --- Dockerfile | 32 +++++++++++++++++++------------- config/nginx/nginx.conf | 31 +++++++++++++++++++++++++++++++ start.sh | 7 ++++--- 3 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 config/nginx/nginx.conf diff --git a/Dockerfile b/Dockerfile index 6551f656b..b5edd9bf9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,31 +4,37 @@ 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 vim -RUN apk add --no-cache python3 && \ +RUN apk add --no-cache python3 nginx && \ python3 -m ensurepip && \ rm -r /usr/lib/python*/ensurepip && \ pip3 install --upgrade pip setuptools && \ - rm -r /root/.cache + rm -r /root/.cache && \ + rm -f /etc/nginx/conf.d/* -RUN mkdir -p /var/interlegis/sapl &&\ +RUN mkdir -p /var/interlegis/sapl && \ apk add --update --no-cache $BUILD_PACKAGES && \ - npm install -g bower - -# Bower aceitar root -RUN touch /root/.bowerrc \ -&& chmod 751 /root/.bowerrc \ -&& echo "{ \"allow_root\": true }" >> /root/.bowerrc \ -&& npm cache clean + npm install -g bower && \ + npm cache clean WORKDIR /var/interlegis/sapl/ ADD . /var/interlegis/sapl/ COPY start.sh /var/interlegis/sapl/ +COPY config/nginx/sapl.conf /etc/nginx/conf.d +COPY config/nginx/nginx.conf /etc/nginx/nginx.conf + +RUN pip install -r /var/interlegis/sapl/requirements/requirements.txt --upgrade setuptools && \ + rm -r /root/.cache && \ + rm -r /tmp/* -RUN chmod +x /var/interlegis/sapl/start.sh +RUN python3 manage.py bower install -- --allow-root && \ + python3 manage.py collectstatic --no-input -RUN pip install -r /var/interlegis/sapl/requirements/requirements.txt --upgrade setuptools +RUN chmod +x /var/interlegis/sapl/start.sh && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log VOLUME ["/var/interlegis/sapl/data", "/var/interlegis/sapl/media", "/var/interlegis/sapl/collected_static"] -ENTRYPOINT ["/var/interlegis/sapl/start.sh"] + +CMD ["/var/interlegis/sapl/start.sh"] diff --git a/config/nginx/nginx.conf b/config/nginx/nginx.conf new file mode 100644 index 000000000..cfea596f1 --- /dev/null +++ b/config/nginx/nginx.conf @@ -0,0 +1,31 @@ +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile off; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/start.sh b/start.sh index 250be13ea..5ee1d7d79 100755 --- a/start.sh +++ b/start.sh @@ -40,12 +40,12 @@ create_env() { create_env -python3 manage.py bower install +#python3 manage.py bower install /bin/sh busy-wait.sh $DATABASE_URL python3 manage.py migrate -python3 manage.py collectstatic --no-input +#python3 manage.py collectstatic --no-input python3 manage.py rebuild_index --noinput user_created=$(python3 create_admin.py 2>&1) @@ -66,4 +66,5 @@ if [ $lack_pwd -eq 0 ]; then fi -/bin/sh gunicorn_start.sh no-venv +/bin/sh gunicorn_start.sh no-venv & +/usr/sbin/nginx -g "daemon off;" From 8998ca2218a6c038c81d81e6441f14119f0aaad7 Mon Sep 17 00:00:00 2001 From: Fabio Rauber Date: Wed, 3 May 2017 14:00:35 -0300 Subject: [PATCH 45/57] Refactored SAPL docker-compose --- docker-compose.yml | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index a073bb4ee..cd899e6c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,3 @@ -server: - image: nginx:latest - ports: - - "80:80" - volumes: - - ./config/nginx:/etc/nginx/conf.d - - ./collected_static:/var/interlegis/sapl/collected_static - - ./media:/var/interlegis/sapl/media - volumes_from: - - web sapldb: image: postgres environment: @@ -16,16 +6,15 @@ sapldb: POSTGRES_DB: sapl PGDATA : /var/lib/postgresql/data/ volumes: - - ./postgres-data/data/:/var/lib/postgresql/data/ - - ./data:/data-import + - sapldb_data:/var/lib/postgresql/data/ ports: - "5532:5432" -web: +sapl: build: . volumes: - - .:/var/interlegis/sapl/ - - ./data:/var/interlegis/sapl/data - - ./media:/var/interlegis/sapl/media - - ./collected_static:/var/interlegis/sapl/collected_static + - sapl_data:/var/interlegis/sapl/data + - sapl_media:/var/interlegis/sapl/media links: - sapldb + ports: + - "80:80" From 701069f5477581c6bf1831daf96bcf9de33aabde Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 3 May 2017 15:16:02 -0300 Subject: [PATCH 46/57] HOT-FIX: reinsert bang bash --- start.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/start.sh b/start.sh index dccee52ba..2a1bb4df6 100755 --- a/start.sh +++ b/start.sh @@ -1,3 +1,5 @@ +#!/bin/sh + create_env() { echo "[ENV FILE] creating .env file..." # check if file exists From 2e0cfd495dee8b1e874571783ee7d67d6af1b075 Mon Sep 17 00:00:00 2001 From: Matheus Veleci Date: Wed, 3 May 2017 16:14:23 -0300 Subject: [PATCH 47/57] =?UTF-8?q?Ajusta=20cria=C3=A7=C3=A3o=20de=20.env=20?= =?UTF-8?q?e=20banco=20sqlite3=20tempor=C3=A1rios=20no=20=20Dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 8 ++++++-- config/env_dockerfile | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 config/env_dockerfile diff --git a/Dockerfile b/Dockerfile index b5edd9bf9..64208fe1b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,13 +28,17 @@ RUN pip install -r /var/interlegis/sapl/requirements/requirements.txt --upgrade rm -r /root/.cache && \ rm -r /tmp/* +COPY config/env_dockerfile /var/interlegis/sapl/sapl/.env + RUN python3 manage.py bower install -- --allow-root && \ - python3 manage.py collectstatic --no-input + python3 manage.py collectstatic --no-input && \ + rm -rf /var/interlegis/sapl/sapl/.env && \ + rm -rf /var/interlegis/sapl/sapl.db RUN chmod +x /var/interlegis/sapl/start.sh && \ ln -sf /dev/stdout /var/log/nginx/access.log && \ ln -sf /dev/stderr /var/log/nginx/error.log -VOLUME ["/var/interlegis/sapl/data", "/var/interlegis/sapl/media", "/var/interlegis/sapl/collected_static"] +VOLUME ["/var/interlegis/sapl/data", "/var/interlegis/sapl/media"] CMD ["/var/interlegis/sapl/start.sh"] diff --git a/config/env_dockerfile b/config/env_dockerfile new file mode 100644 index 000000000..c83fc88f1 --- /dev/null +++ b/config/env_dockerfile @@ -0,0 +1,8 @@ +DATABASE_URL = sqlite:///sapl.db +SECRET_KEY = 'Dockerfile_Key' +DEBUG = False +EMAIL_USE_TLS = True +EMAIL_PORT = 587 +EMAIL_HOST = '' +EMAIL_HOST_USER = '' +EMAIL_HOST_PASSWORD = '' From 95ec95a2a9be2785365d02fc8fd27e584135eed7 Mon Sep 17 00:00:00 2001 From: Matheus Veleci Date: Wed, 3 May 2017 16:17:25 -0300 Subject: [PATCH 48/57] Ajusta start.sh --- start.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/start.sh b/start.sh index dccee52ba..0dd68dd84 100755 --- a/start.sh +++ b/start.sh @@ -1,3 +1,6 @@ +#!/bin/sh + + create_env() { echo "[ENV FILE] creating .env file..." # check if file exists @@ -63,5 +66,5 @@ if [ $lack_pwd -eq 0 ]; then fi -/bin/sh gunicorn_start.sh no-venv & +/bin/sh gunicorn_start.sh no-venv & /usr/sbin/nginx -g "daemon off;" From fa73345651dc35c64a75fe4a5dce44c9a986818c Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 4 May 2017 17:52:29 -0300 Subject: [PATCH 49/57] =?UTF-8?q?Gera=20migra=C3=A7=C3=A3o=20de=20disposit?= =?UTF-8?q?ivo=20em=20AsssuntoMateria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0004_auto_20170504_1751.py | 32 +++++++++++++++++++ .../migrations/0002_auto_20170504_1751.py | 25 +++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 sapl/materia/migrations/0004_auto_20170504_1751.py create mode 100644 sapl/parlamentares/migrations/0002_auto_20170504_1751.py diff --git a/sapl/materia/migrations/0004_auto_20170504_1751.py b/sapl/materia/migrations/0004_auto_20170504_1751.py new file mode 100644 index 000000000..49a7e8938 --- /dev/null +++ b/sapl/materia/migrations/0004_auto_20170504_1751.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2017-05-04 17:51 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0003_auto_20170403_1505'), + ] + + operations = [ + migrations.AlterField( + model_name='assuntomateria', + name='dispositivo', + field=models.CharField(blank=True, default='', max_length=200, verbose_name='Descrição do Dispositivo Legal'), + preserve_default=False, + ), + migrations.AlterField( + model_name='materiaassunto', + name='assunto', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='materia.AssuntoMateria', verbose_name='Assunto'), + ), + migrations.AlterField( + model_name='materiaassunto', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='materia.MateriaLegislativa', verbose_name='Matéria'), + ), + ] diff --git a/sapl/parlamentares/migrations/0002_auto_20170504_1751.py b/sapl/parlamentares/migrations/0002_auto_20170504_1751.py new file mode 100644 index 000000000..7e7039e94 --- /dev/null +++ b/sapl/parlamentares/migrations/0002_auto_20170504_1751.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2017-05-04 17:51 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('parlamentares', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='coligacao', + name='numero_votos', + field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Nº Votos Recebidos (Coligação)'), + ), + migrations.AlterField( + model_name='mandato', + name='votos_recebidos', + field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Votos Recebidos (Mandato)'), + ), + ] From 0f5331c9810b443e8c4a7ffe121b844323f21837 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 4 May 2017 17:56:58 -0300 Subject: [PATCH 50/57] =?UTF-8?q?Remove=20CSS=20desnecess=C3=A1rios.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/static/styles/app.css | 1 - sapl/static/styles/compilacao.css | 1 - sapl/static/styles/style_tinymce.css | 8 -------- 3 files changed, 10 deletions(-) delete mode 100644 sapl/static/styles/app.css delete mode 100644 sapl/static/styles/compilacao.css delete mode 100644 sapl/static/styles/style_tinymce.css diff --git a/sapl/static/styles/app.css b/sapl/static/styles/app.css deleted file mode 100644 index e7146b1f4..000000000 --- a/sapl/static/styles/app.css +++ /dev/null @@ -1 +0,0 @@ -.logo img{width:40px;height:40px;margin:5px 15px}.vcenter{display:inline-block;vertical-align:middle;float:none;padding:10px}nav.navbar{border-radius:0;font-size:15px}nav .navbar-nav>li>a{padding-top:0px;padding-bottom:0px;line-height:75px}nav .navbar-nav>li>a:hover{background-color:#23527c}nav .navbar-nav>li:nth-child(2)>.dropdown-menu{right:auto}nav .navbar-nav:last-child>li:last-child a{padding-right:0px}.masthead{padding:10px}.masthead .nav{clear:both}.masthead .navbar-brand{color:inherit;font-size:24px}.masthead .navbar-brand img.img-responsive{height:95px;margin-right:15px}.masthead .navbar-brand small{color:#93A4AA;font-size:75%;line-height:25px}.navbar{margin-bottom:0}.navbar-brand{padding:0px}h1,.h1{font-size:30px}h2,.h2{font-size:24px}h3,.h3{font-size:20px}h4,.h4{font-size:16px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}.page-header{margin:20px 0px 10px}.btn:hover,.btn:focus{color:inherit}.caret.top{transform:rotate(180deg)}.btn-default.btn-excluir{color:#d9534f}.btn-default.btn-excluir:hover{color:#fff;border-color:#de6764;background-color:#de6764}.controls-file{padding:10px;border:1px solid #d6e1e5;border-radius:4px}.controls-file label.checkbox-inline{margin:0px;display:block}.controls-radio-checkbox{padding:0px;border:1px solid #d6e1e5;border-radius:4px;min-height:20px}.controls-radio-checkbox .help-block{margin:15px;padding:15px;border:2px dashed #d6e1e5}.controls-radio-checkbox label{padding:5px}.controls-radio-checkbox label .icons{top:5px;left:8px}.controls-radio-checkbox label.checkbox-inline,.controls-radio-checkbox label.radio-inline{padding:8px;padding-left:36px}.controls-radio-checkbox label.checkbox-inline .icons,.controls-radio-checkbox label.radio-inline .icons{top:8px;left:8px}.controls-radio-checkbox .checkbox,.controls-radio-checkbox .radio,.controls-radio-checkbox .checkbox-inline,.controls-radio-checkbox .radio-inline{margin:0}.controls-radio-checkbox .checkbox:hover,.controls-radio-checkbox .radio:hover,.controls-radio-checkbox .checkbox-inline:hover,.controls-radio-checkbox .radio-inline:hover{background-color:#d6e1e5}p.control-label{font-weight:bold}.legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5;clear:both}.grid-gutter-width-right{margin-right:15px}html{position:relative;min-height:100%}body{margin-bottom:160px}.footer{position:absolute;bottom:0;width:100%;height:140px;background:#364347 none repeat scroll 0% 0%;color:white;text-align:center}.footer p{color:white;margin-top:10px}.footer .container{padding-top:25px}.pagination{padding-top:25px}.modal .alert{margin-bottom:0}fieldset fieldset{font-size:95%}fieldset fieldset legend{font-size:18px}.avatar-parlamentar{height:84px;width:84px}#conteudo{position:relative;padding:2em 1.5em 1.5em 1.5em;overflow:hidden;font-size:100%;text-align:left;min-height:350px;max-width:1000px;margin:0 auto}#conteudo a:hover{color:#444;-webkit-transition:0.3s ease-in;-moz-transition:0.3s ease-in;-o-transition:0.3s ease-in}#homeIndex{text-align:center}.homeBanner span{color:white;font-size:32px;font-weight:600;display:inline-block;vertical-align:middle;padding:2px 45px 4px;border:2px solid}.homeBanner::after{display:inline-block;vertical-align:middle;height:100%}.homeBlock{display:inline-block;position:relative;background-color:#F3F3F3;width:190px;height:260px;margin:3px;text-align:center;font-size:0;overflow:hidden}.homeBlock>a{display:block;position:absolute;width:100%;height:100%;top:0;left:0}.homeBlock::after{content:'';display:inline-block;vertical-align:middle;height:100%;overflow:visible;clear:none;visibility:initial}.homeContent{position:relative;padding:10px;text-align:justify;font-size:14px;color:#FFF;opacity:0;transition:opacity 0.5s ease;display:inline-block;vertical-align:middle}.homeContent p{display:block;line-height:13px;font-size:80%;color:white}.homeIcon{position:relative;display:inline-block;width:105px;height:105px;border-radius:50%;background:#364347;z-index:1}.homeIcon::before{content:'';position:absolute;width:100%;height:100%;border-radius:50%;background:#364347;top:0;left:0;transform:scale(0.95);transition:transform 0.6s ease}.homeIcon img{position:absolute;margin:auto;top:0;bottom:0;right:0;left:0;transition:opacity 0.4s 0.4s ease}.homeFront{position:absolute;top:46%;width:100%;font-size:0;transform:translateY(-60%)}.homeFront h2{position:absolute;margin-top:18px;font-size:22px;font-weight:700;color:#595959 !important;width:100%;padding:0 6%;z-index:0}.homeTitle{display:block;height:32px;text-align:center;width:100%;opacity:0;transition:opacity 0.4s ease}.homeTitle::before{content:'';display:inline-block;vertical-align:middle;height:100%}.homeTitle h2{display:inline-block;vertical-align:middle;max-width:110px;font-size:14px;color:white !important;line-height:1em}.homeTitle img{display:inline-block;vertical-align:middle;height:30px;margin-right:5px}.homeBlock:hover .homeIcon::before{transform:scale(3.6) translateY(7px)}.homeBlock:hover .homeContent{opacity:1;transition-delay:0.2s}.homeBlock:hover .homeIcon img{opacity:0;transition-duration:0.2s;transition-delay:0s}.homeBlock:hover .homeTitle{opacity:1}h1,h2,h3,h4,h5,h6,form,dl,dt,dd,p,div,img,a{margin:0;padding:0}p{margin:0.5em 0}.manual li{display:list-item;line-height:1.5em;padding-right:0}.manual li a{background-color:transparent;border:none;border-radius:none;padding:0}.manual,.manual ul{padding-left:1.5em;list-style-type:none;margin-top:0;font-size:100%}@media (max-width: 1199px){.masthead .navbar-brand{font-size:22px}.masthead .navbar-brand img.img-responsive{height:60px;width:60px;margin-right:7.5px}.navbar-nav>li>a{padding-left:10.71429px;padding-right:10.71429px}}@media (max-width: 1091px){.navbar-nav>li>a{padding-left:7.5px;padding-right:7.5px}}@media (min-width: 1092px) and (max-width: 1199px){.container{width:1070px}} diff --git a/sapl/static/styles/compilacao.css b/sapl/static/styles/compilacao.css deleted file mode 100644 index ed50d8998..000000000 --- a/sapl/static/styles/compilacao.css +++ /dev/null @@ -1 +0,0 @@ -a:link:after,a:visited:after{content:""}.test_import:nth-child(even){background-color:#ccc}#wait_message{display:block;position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(220,220,220,0.75);z-index:99}#wait_message #msg{position:relative;margin:20% auto;padding:1.2em 2em;max-width:600px;text-align:center;font-size:1.5em;color:#677;border:1px solid #eee;background-color:#fff !important;box-shadow:0 1px 2px #999}.text-center{text-align:center}.cp-notify{z-index:9999;position:fixed;top:2em;left:50%;min-width:600px;transform:translate(-50%, 0);transition:all 0.4s ease;opacity:0.97}.cp-notify.hide{opacity:0;top:-1000px;display:block !important;transition:all 0.4s ease}.cp-notify .message{padding:1em;border:2px solid rgba(0,0,0,0.1);border-radius:4px;color:rgba(0,0,0,0.6);line-height:1em;font-size:1.3em;text-align:center;box-shadow:0 0 100px rgba(0,0,0,0.2)}.cp .desativado .dtxt,.cp .dpt .dptt>a.desativado .dtxt,.cp .desativado .dtxt *,.cp .dpt .dptt>a.desativado .dtxt *,.cp .desativado .dpt-link,.cp .dpt .dptt>a.desativado .dpt-link,.cp .desativado .dpt-link *,.cp .dpt .dptt>a.desativado .dpt-link *{text-decoration:line-through;color:#999 !important}.cp .desativado .dtxt table,.cp .dpt .dptt>a.desativado .dtxt table,.cp .desativado .dtxt table td,.cp .dpt .dptt>a.desativado .dtxt table td,.cp .desativado .dtxt * table,.cp .dpt .dptt>a.desativado .dtxt * table,.cp .desativado .dtxt * table td,.cp .dpt .dptt>a.desativado .dtxt * table td,.cp .desativado .dpt-link table,.cp .dpt .dptt>a.desativado .dpt-link table,.cp .desativado .dpt-link table td,.cp .dpt .dptt>a.desativado .dpt-link table td,.cp .desativado .dpt-link * table,.cp .dpt .dptt>a.desativado .dpt-link * table,.cp .desativado .dpt-link * table td,.cp .dpt .dptt>a.desativado .dpt-link * table td{border:1px dotted #ccc}.cp a{text-decoration:none;cursor:pointer}.cp .diff .desativado,.cp .diff .dpt .dptt>a.desativado,.cp .dpt .diff .dptt>a.desativado,.cp .diff .desativado *,.cp .diff .dpt .dptt>a.desativado *,.cp .dpt .diff .dptt>a.desativado *{text-decoration:line-through;color:#ddd !important;font-size:90%}.cp .diff .added{color:#04DE2C}.cp .dpt{font-size:1em;position:relative}.cp .dpt.indent{padding-left:1em}.cp .dpt .ementa{padding:2em 0em 2em 35%;font-weight:bold}.cp .dpt .titulo_generico,.cp .dpt .anexo,.cp .dpt .disp_preliminares,.cp .dpt .disp_gerais,.cp .dpt .disp_transitorias,.cp .dpt .disp_finais,.cp .dpt .parte,.cp .dpt .livro,.cp .dpt .titulo,.cp .dpt .capitulo,.cp .dpt .secao,.cp .dpt .subsecao,.cp .dpt .itemsecao{text-align:center;font-weight:bold;margin-bottom:1em;font-size:1.5em;margin-top:3em}.cp .dpt .titulo{margin-top:2em}.cp .dpt .capitulo{margin-top:1.5em;font-size:1.3em}.cp .dpt .secao{margin-top:1.2em;margin-bottom:0.7em;font-size:1.2em}.cp .dpt .subsecao,.cp .dpt .itemsecao{margin-top:1em;margin-bottom:0.6em;font-size:1.2em;font-style:italic}.cp .dpt .artigo{font-size:1.15em;float:left}.cp .dpt .artigo .dptt{position:relative}.cp .dpt .caput{margin-top:0.3333em;font-size:1.15em}.cp .dpt .paragrafo{font-size:1.1em;margin-top:0.2222em}.cp .dpt .inciso{font-size:1.1em;margin-top:0.1667em}.cp .dpt .alinea{font-size:1.0em;margin-top:2px}.cp .dpt .item{font-size:1.0em;margin-top:2px}.cp .dpt .bloco_alteracao{padding-left:10%;font-style:italic;color:#018}.cp .dpt .bloco_alteracao a{text-decoration:underline}.cp .dpt .bloco_alteracao a,.cp .dpt .bloco_alteracao table,.cp .dpt .bloco_alteracao table td{color:#018 !important}.cp .dpt .dn{font-weight:normal;position:relative;font-size:70%}.cp .dpt .dn p,.cp .dpt .dn ul{font-weight:normal;margin:0 0 0 0;list-style:none;padding:0}.cp .dpt .dn .dnl{display:block;text-align:left !important}.cp .dpt .dn .dnl *{display:inline}.cp .dpt .dn .dnl .bullet{padding:0 0.333em;display:inline-block}.cp .dpt .dn .dnl .dnli{min-height:2.5em}.cp .dpt .dn .dnl .dnli:hover ul{transition:opacity 0.5s linear, clip 0s 0.3s;clip:auto;opacity:1;background:rgba(230,230,230,0.9)}.cp .dpt .dn .dnl .dnli ul{transition:opacity 0.5s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;background:transparent;right:0;padding:0.2em 0.5em 0em 0.5em;border:1px solid #c7e3d3;border-top:0px;font-size:1.5rem}.cp .dpt .dn .dnl .dnli ul li{display:table-cell;color:#aaa}.cp .dpt .dn .dnl .dnli ul li:hover{color:#787}.cp .dpt .dn .dnl .dnli ul li:hover a{color:#27AE60 !important}.cp .dpt .dn .dnl .dnli ul li .nowner{color:#27AE60 !important}.cp .dpt .dn .dnl .dnli .ntitulo{font-weight:bold;color:#03A203;text-decoration:none}.cp .dpt .dn .dnl .dnli .ntitulo a{color:#294 !important}.cp .dpt .dn .dnl .dnli .ntexto{color:#06D806}.cp .dpt .dn .dnl .dnli .ntexto a{color:#03A203 !important}.cp .dpt .dn .dnl:hover{display:block}.cp .dpt .dn .dnl:hover *{display:block}.cp .dpt .dn .dnl:hover>.bullet{display:none}.cp .dpt .dn .dnl:hover .dnli{margin-top:0.5em;border-top:1px solid #c7e3d3}.cp .dpt .dptt>a{color:#444444}.cp .dpt .dptt>a.nota-alteracao{color:#02baf2;font-size:0.75em}.cp .dpt .dptt>a.nota-alteracao:hover{text-decoration:underline}.cp .dpt .dptt .dne{position:absolute;display:block;right:0;left:0;top:0;height:0;transform:scaleX(0);transform-origin:right;transition:all 0.3s ease;border-top:1px solid #2980B9}.cp .dpt .dptt .dne ul.btns-action{list-style:none;padding:0;position:absolute;right:0;background-color:#2980B9}.cp .dpt .dptt .dne ul.btns-action li{float:left}.cp .dpt .dptt .dne ul.btns-action li:hover{background-color:rgba(0,0,0,0.1)}.cp .dpt .dptt .dne ul.btns-action li a{color:white;padding:0.15em 1em 0;display:inline-block}.cp .dpt .dptt .dne-nota{position:relative;transform:scaleX(1);height:auto;border-top:0px}.cp .dpt .dptt .dne-nota ul.btns-action{display:none}.cp .dpt .dptt .dne-nota .dne-form{margin:1em -2em 0em;text-align:left;font-size:1.6rem}.cp .dpt .dptt:hover .dne{height:0.1667rem;transform:scaleX(1);transition-delay:1s}.cp .dpt .dptt:hover .dne-nota{height:auto;transition-delay:0s}.cp .tipo-vigencias{list-style:none;position:fixed;bottom:0px;left:50%;transform:translate(-50%, 0);margin:0;padding:0;background-color:#2980B9;z-index:1000;opacity:0.9;transition:all 0.3s ease-in-out}.cp .tipo-vigencias li{display:inline-block;border-left:1px solid #fff;float:left}.cp .tipo-vigencias li a{color:white;padding:0.3em 1em 0;display:inline-block;font-size:110%;cursor:pointer}.cp .tipo-vigencias li a.selected{background-color:rgba(0,0,0,0.5)}.cp .tipo-vigencias li:hover{background-color:rgba(0,0,0,0.2)}.cp .tipo-vigencias:hover{opacity:1}.cp.cpe .desativado,.cp.cpe .dpt .dptt>a.desativado{text-decoration:line-through;color:#999 !important}.cp.cpe .desativado table,.cp.cpe .dpt .dptt>a.desativado table,.cp.cpe .desativado table td,.cp.cpe .dpt .dptt>a.desativado table td{border:1px dotted #ccc}.cp.cpe .desativado a.nota-alteracao *{color:#02baf2 !important}.cp.cpe .dpt{display:block}.cp.cpe .dpt>.dpt-actions-fixed{position:absolute;right:-0.8em;top:-0.8em;z-index:3;opacity:0}.cp.cpe .dpt>.dpt-actions-fixed .activate{display:none}.cp.cpe .dpt>.dpt-actions-fixed .deactivate{display:inline}.cp.cpe .dpt>.dpt-actions-fixed .btn-dpt-edit.btn-default{color:#333}.cp.cpe .dpt>.dpt-actions-fixed .btn-dpt-edit.btn-default:hover{color:#fff;background-color:#02baf2}.cp.cpe .dpt>.dpt-actions,.cp.cpe .dpt>.dpt-actions-bottom{display:none}.cp.cpe .dpt>.dpt-text{cursor:text;min-height:30px;border:1px solid transparent}.cp.cpe .dpt>.dpt-text:hover,.cp.cpe .dpt>.dpt-text.hover-fixed{background-color:rgba(0,0,0,0.01);color:#2980B9;border:1px solid #eee;transition:color 0.3s ease}.cp.cpe .dpt>.dpt-text.artigo{float:none}.cp.cpe .dpt>.dpt-text a.link-rotulo{color:#000}.cp.cpe .dpt:hover>.dpt-actions-fixed{opacity:1}.cp.cpe .dpt:hover>.dpt-actions-fixed:hover ~ .dpt-text{background-color:rgba(0,0,0,0.01);color:#2980B9;border:1px solid #eee;transition:color 0.3s ease}.cp.cpe .dpt .semtexto{font-weight:bold;color:#9aaed6}.cp.cpe .dpt .semtexto:hover{color:#5f76a4}.cp.cpe .dpt-alts{margin:0;margin-bottom:1em;padding:0;background-color:transparent;min-height:100px;border:2px dashed #fff}.cp.cpe .dpt-alts:hover{border-color:#d9ddde}.cp.cpe .dpt-alts:empty{border-color:#ddd}.cp.cpe .dpt-alts.drag{width:100% !important;border-color:#d9ddde}.cp.cpe .dpt-alts.drag .dpt{transition-duration:0s !important}.cp.cpe .dpt-alts .dpt{width:100% !important;box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,0.12),0 2px 4px rgba(0,0,0,0.24);padding:0;margin:0;background-color:#edf0f1;height:auto !important;min-height:2em;z-index:1}.cp.cpe .dpt-alts .dpt:not(:first-child){border-top:1px solid white}.cp.cpe .dpt-alts .dpt>.dpt-text{padding:0.3em 1em;margin-top:0;margin-bottom:0}.cp.cpe .dpt-alts .dpt>.dpt-text a.link-rotulo{text-decoration:underline}.cp.cpe .dpt-alts .dpt-selected.dpt{margin:0em -0.5em}.cp.cpe .dpt-selected.dpt{width:auto !important;margin:1em -0.5em;border:1px solid #fad46b !important;padding:0;background-color:#fafafa;border-radius:3px;z-index:4}.cp.cpe .dpt-selected.dpt>.dpt-text{border:1px solid transparent}.cp.cpe .dpt-selected.dpt>.dpt-text:hover{border:1px solid transparent;background-color:transparent}.cp.cpe .dpt-selected.dpt>.dpt-form{margin-bottom:0em}.cp.cpe .dpt-selected.dpt>.dpt-actions,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom{display:table;background-color:#e5e5e5;padding:1em;margin-bottom:0em;width:100%}.cp.cpe .dpt-selected.dpt>.dpt-actions>.btn-action,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom>.btn-action{display:table-cell;float:none}.cp.cpe .dpt-selected.dpt>.dpt-actions .btn-excluir,.cp.cpe .cp.cpe1_old_apagar .dpt-selected.dpt>.dpt-actions .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1_old_apagar .cp.cpe .dpt-selected.dpt>.dpt-actions .csform .actions_inserts>li>a.btn-salvar,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .btn-excluir,.cp.cpe .cp.cpe1_old_apagar .dpt-selected.dpt>.dpt-actions-bottom .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1_old_apagar .cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .csform .actions_inserts>li>a.btn-salvar{display:inline-block;opacity:0.3}.cp.cpe .dpt-selected.dpt>.dpt-actions .btn-excluir:hover,.cp.cpe .cp.cpe1_old_apagar .dpt-selected.dpt>.dpt-actions .csform .actions_inserts>li>a.btn-salvar:hover,.cp.cpe1_old_apagar .cp.cpe .dpt-selected.dpt>.dpt-actions .csform .actions_inserts>li>a.btn-salvar:hover,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .btn-excluir:hover,.cp.cpe .cp.cpe1_old_apagar .dpt-selected.dpt>.dpt-actions-bottom .csform .actions_inserts>li>a.btn-salvar:hover,.cp.cpe1_old_apagar .cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .csform .actions_inserts>li>a.btn-salvar:hover{opacity:1}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom{margin:0}.cp.cpe .dpt-selected .dpt-block{border-top:1px solid #e5e5e5 !important;opacity:0.6;transition:opacity 0.4s ease}.cp.cpe .dpt-selected .dpt-block:hover{opacity:1}.cp.cpe .dpt-selected .dpt-text{opacity:0.7;margin:0;padding:0.7em}.cp.cpe .dpt-selected .dpt-text:hover{opacity:1;background-color:#f5f5f5}.cp.cpe .dpt-selected .dpt-alts{margin:1em}.cp.cpe .dpt-selected .dpt-alts .dpt{box-shadow:0 0 0}.cp.cpe .dpt-selected>.dpt-actions-fixed{opacity:1;top:-12px;right:0.5em}.cp.cpe .dpt-selected>.dpt-actions-fixed .activate{display:inline}.cp.cpe .dpt-selected>.dpt-actions-fixed .deactivate{display:none}.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit{padding-top:2px;padding-bottom:1px}.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit.btn-default{background-color:#fad46b;border:1px solid #fad46b}.cp.cpe .dpt-selected .dropdown-menu.dropdown-menu-left{right:auto !important;left:0;padding:2px 0}.cp.cpe .dpt-selected .dropdown-menu.dropdown-menu-left>.top.arrow{right:88%;left:auto}.cp.cpe .dpt-selected .dropdown-menu li a{padding-top:2px;padding-bottom:2px}.cp.cpe .dpt-selected .btn-group .radius-right{border-bottom-right-radius:4px !important;border-top-right-radius:4px !important}.cp.cpe .dpt-selected:hover>.dpt-actions-fixed{opacity:1}.cp.cpe1_old_apagar{margin-bottom:15em}.cp.cpe1_old_apagar .desativado,.cp.cpe1_old_apagar .dpt .dptt>a.desativado,.cp.cpe1_old_apagar .desativado *,.cp.cpe1_old_apagar .dpt .dptt>a.desativado *{text-decoration:line-through;color:#999 !important}.cp.cpe1_old_apagar .desativado table,.cp.cpe1_old_apagar .dpt .dptt>a.desativado table,.cp.cpe1_old_apagar .desativado table td,.cp.cpe1_old_apagar .dpt .dptt>a.desativado table td,.cp.cpe1_old_apagar .desativado * table,.cp.cpe1_old_apagar .dpt .dptt>a.desativado * table,.cp.cpe1_old_apagar .desativado * table td,.cp.cpe1_old_apagar .dpt .dptt>a.desativado * table td{border:1px dotted #ccc}.cp.cpe1_old_apagar a{text-decoration:none;cursor:pointer}.cp.cpe1_old_apagar .dpt{position:relative;display:block}.cp.cpe1_old_apagar .dpt .semtexto{font-weight:bold;color:#BFD1F6}.cp.cpe1_old_apagar .dpt .artigo{float:none}.cp.cpe1_old_apagar .dpt .caput{margin-top:0}.cp.cpe1_old_apagar .dpt>.actions_right,.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left{color:#fff;right:0em;position:absolute;opacity:0;transition:all 0.4s ease-in-out;z-index:1000}.cp.cpe1_old_apagar .dpt>.actions_right a.btn-bloco,.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left a.btn-bloco{background-color:#3498db;color:#ffffff !important;padding:8px 18px 6px;display:inline-block;line-height:1;float:right}.cp.cpe1_old_apagar .dpt>.actions_right a.btn-bloco:hover,.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left a.btn-bloco:hover{opacity:1;background-image:-webkit-linear-gradient(top, #1c81c4, #0b6dad);background-image:-moz-linear-gradient(top, #1c81c4, #0b6dad);background-image:-ms-linear-gradient(top, #1c81c4, #0b6dad);background-image:-o-linear-gradient(top, #1c81c4, #0b6dad);background-image:linear-gradient(to bottom, #1c81c4, #0b6dad)}.cp.cpe1_old_apagar .dpt:hover>.actions_right,.cp.cpe1_old_apagar .dpt-selected .csform .dpt:hover>.actions_left{opacity:1}.cp.cpe1_old_apagar .dpt .bloco{display:block;clear:both}.cp.cpe1_old_apagar .dpt .bloco *:hover{color:#27AE60}.cp.cpe1_old_apagar .dpt .bloco .de{cursor:pointer}.cp.cpe1_old_apagar .dpt .articulacao{border-top:2px solid #e5e5e5;margin:2em 0}.cp.cpe1_old_apagar .dpt .bloco_alteracao{margin:1em 0;padding:0em;background-color:transparent;min-height:100px;border:2px dashed #fff}.cp.cpe1_old_apagar .dpt .bloco_alteracao:hover{border-color:#d9ddde}.cp.cpe1_old_apagar .dpt .bloco_alteracao.drag{width:100% !important;border-color:#d9ddde}.cp.cpe1_old_apagar .dpt .bloco_alteracao.drag .dpt{transition-duration:0s !important}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt{width:100% !important;box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,0.12),0 2px 4px rgba(0,0,0,0.24);padding:0.3em 1em;margin:0;background-color:#edf0f1;z-index:1}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt:not(:first-child){border-top:1px solid white}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt.ui-draggable div{cursor:pointer}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt.dpt-comp-selected{transition:all 0.3s ease;width:auto !important;margin:2em -3.7em;box-shadow:0 0 6px rgba(0,0,0,0.16),0 6px 12px rgba(0,0,0,0.32)}.cp.cpe1_old_apagar .dpt-selected{font-size:1em;border:0px solid #CCC;margin:1em -1.8em 1em -1.8em;padding:2.2em 2.2em 1.6em 2.2em;box-shadow:-4px 15px 15px rgba(0,0,0,0.1),0px 6px 6px rgba(0,0,0,0.23);background-image:-webkit-linear-gradient(top, #eaeaee, #ddd);background-image:-moz-linear-gradient(top, #eaeaee, #ddd);background-image:-ms-linear-gradient(top, #eaeaee, #ddd);background-image:-o-linear-gradient(top, #eaeaee, #ddd);background-image:linear-gradient(to bottom, #eaeaee, #ddd)}.cp.cpe1_old_apagar .dpt-selected ul{list-style:none;margin:0;padding:0}.cp.cpe1_old_apagar .dpt-selected .semtexto{color:#999}.cp.cpe1_old_apagar .dpt-selected .bloco{opacity:0.5}.cp.cpe1_old_apagar .dpt-selected .bloco:hover{opacity:1}.cp.cpe1_old_apagar .dpt-selected .bloco a:hover{background:transparent}.cp.cpe1_old_apagar .dpt-selected>.bloco{opacity:1;margin:1em}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao{margin:0;padding:1em;border:0 transparent;background-image:-webkit-linear-gradient(top, #eaeaee, #ddd);background-image:-moz-linear-gradient(top, #eaeaee, #ddd);background-image:-ms-linear-gradient(top, #eaeaee, #ddd);background-image:-o-linear-gradient(top, #eaeaee, #ddd);background-image:linear-gradient(to bottom, #eaeaee, #ddd)}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao:hover{border-color:transparent}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao.drag{width:100% !important}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao.drag .dpt{transition-duration:0s !important}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao .dpt{width:auto !important;transition:all 0.3s ease;background-color:white}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao .dpt:not(:first-child){border-top:0px solid white}.cp.cpe1_old_apagar .dpt-selected>.dpt{padding:0}.cp.cpe1_old_apagar .dpt-selected>.dpt:last-child{padding-bottom:1em}.cp.cpe1_old_apagar .dpt-selected>.actions_right a.btn-bloco,.cp.cpe1_old_apagar .dpt-selected .csform .dpt-selected>.actions_left a.btn-bloco{display:none}.cp.cpe1_old_apagar .dpt-selected .csform{display:block;clear:both;z-index:9;position:static}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action{-webkit-animation:fadeIn 1s ease-in-out;-moz-animation:fadeIn 1s ease-in-out;-o-animation:fadeIn 1s ease-in-out;opacity:1;position:absolute;display:table;transition:all 0.4s ease-in-out}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action a{color:#16407c;display:block;background:transparent;vertical-align:middle;text-align:center;font-weight:normal;text-shadow:0 0 10px rgba(0,0,0,0.3);padding:0.33em 0.4em}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li{position:relative;display:table-cell;vertical-align:top}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li:hover{background-color:rgba(255,255,255,0.5)}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li:hover>a{text-shadow:0 0 5px #777;color:#0a5}.cp.cpe1_old_apagar .dpt-selected .csform .label_status{position:absolute;bottom:0;right:0;color:#889;padding:0.3em;font-size:80%;text-align:right;z-index:15;display:table}.cp.cpe1_old_apagar .dpt-selected .csform .label_status li{display:table-cell;padding:0 0.5em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents{z-index:11;top:0em;left:0em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents a{padding:0.62em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents div,.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents li{font-size:80%;display:table-cell;vertical-align:middle;border-right:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents div{padding:0 0.4em;font-stretch:condensed;font-variant:small-caps;font-weight:bold;text-shadow:0 0 10px #fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents>li:hover a{color:#16407c;font-weight:normal}.cp.cpe1_old_apagar .dpt-selected .csform .actions_top,.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom{top:0em;right:0em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_top a,.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom a{padding-right:1em;padding-left:1em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_top li,.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom li{display:table-cell;vertical-align:middle;border-left:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom{top:auto;left:0;bottom:0;display:inline-block;border-top:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom a{padding:0 0.4em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom li{border:0px;border-right:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_right,.cp.cpe1_old_apagar .dpt-selected .csform .actions_left{top:2.2em;right:0em;bottom:0;display:block}.cp.cpe1_old_apagar .dpt-selected .csform .actions_right li,.cp.cpe1_old_apagar .dpt-selected .csform .actions_left li{width:2.2em;display:block;border-bottom:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_right li:first-child,.cp.cpe1_old_apagar .dpt-selected .csform .actions_left li:first-child{border-top:1px solid #CCC}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left{right:auto;left:0em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts{background:transparent;position:relative;z-index:19;display:table;width:100%}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li{display:table-cell}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li:hover>a{background-image:-webkit-linear-gradient(top, #1c81c4, #0b6dad);background-image:-moz-linear-gradient(top, #1c81c4, #0b6dad);background-image:-ms-linear-gradient(top, #1c81c4, #0b6dad);background-image:-o-linear-gradient(top, #1c81c4, #0b6dad);background-image:linear-gradient(to bottom, #1c81c4, #0b6dad)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a{background-image:-webkit-linear-gradient(top, #3498DB, #2980C9);background-image:-moz-linear-gradient(top, #3498DB, #2980C9);background-image:-ms-linear-gradient(top, #3498DB, #2980C9);background-image:-o-linear-gradient(top, #3498DB, #2980C9);background-image:linear-gradient(to bottom, #3498DB, #2980C9);border-right:1px solid #fff;padding:0.2em;display:block;color:white;text-align:center;white-space:nowrap}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar{text-align:left;background:#A70808;color:#c99;padding-left:1.7em;position:relative}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir:hover,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:hover{background-color:#c70808;color:#ecc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir::before,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before{z-index:20;position:absolute;background:url(/static/img/icon_delete_white.png) no-repeat 50% 50%;content:"";top:0;left:0;display:block;color:black;margin-left:0.4em;height:100%;width:2em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar{background:#1f8b4d;color:white}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:hover{background:#2d9c5c;color:white}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before{background:url(/static/img/icon_save_white.png) no-repeat 50% 50%}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a span{padding:0 0.7em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li:last-child>a{border-right:0px solid #fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li:nth-child(even) a{background:#3385CA}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li a{border-right:1px solid #fff;display:block;color:white;background:#2980C9;font-size:80%;padding:0.23em 1em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li a:hover{background:#0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior{table-layout:fixed}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul{transform:translateY(30px);transition:transform 0.1s linear, opacity 0.1s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;margin-left:0.5em;box-shadow:0px 6px 18px rgba(0,0,0,0.19),0px 2px 6px rgba(0,0,0,0.23);-webkit-transition-delay:0.4s;transition-delay:0.4s}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li a{border-right:0px !important}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child::before{border-width:0.375rem;border-style:inset inset solid;content:"";display:block;height:0px;width:0px;border-color:transparent transparent #3385CA;position:absolute;top:-0.71rem;left:0.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child:hover::before{border-color:transparent transparent #0A5EA4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul::after{content:"";position:absolute;z-index:-1;left:0;top:rem-calc(-25px);height:rem-calc(25px);width:100%;transition:all 0.3s cubic-bezier(0.55, 0, 0.1, 1)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior:hover>ul{transform:translateY(7px);transition:transform 0.4s linear, opacity 0.4s linear, clip 0s 0.2s;opacity:1;clip:rect(-100px, 2000px, 2000px, -100px)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir{display:block;position:static}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{transform:translateY(30px);transition:transform 0.1s linear, opacity 0.1s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;margin-left:0.5em;box-shadow:0px 6px 18px rgba(0,0,0,0.19),0px 2px 6px rgba(0,0,0,0.23);-webkit-transition-delay:0.4s;transition-delay:0.4s}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a{border-right:0px !important}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child::before{border-width:0.375rem;border-style:inset inset solid;content:"";display:block;height:0px;width:0px;border-color:transparent transparent #3385CA;position:absolute;top:-0.71rem;left:0.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:hover::before{border-color:transparent transparent #0A5EA4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul::after{content:"";position:absolute;z-index:-1;left:0;top:rem-calc(-25px);height:rem-calc(25px);width:100%;transition:all 0.3s cubic-bezier(0.55, 0, 0.1, 1)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir:hover>ul{transform:translateY(7px);transition:transform 0.4s linear, opacity 0.4s linear, clip 0s 0.2s;opacity:1;clip:rect(-100px, 2000px, 2000px, -100px)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{right:0.5em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a{background-color:#A70808}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a:hover{background:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child::before{border-color:transparent transparent #A70808;right:10%;left:auto}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:hover::before{border-color:transparent transparent #c70808}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo{z-index:2000}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul{transform:translateY(30px);transition:transform 0.1s linear, opacity 0.1s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;margin-left:0.5em;box-shadow:0px 6px 18px rgba(0,0,0,0.19),0px 2px 6px rgba(0,0,0,0.23);-webkit-transition-delay:0.4s;transition-delay:0.4s}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li a,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li a{border-right:0px !important}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li:first-child::before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li:first-child::before{border-width:0.375rem;border-style:inset inset solid;content:"";display:block;height:0px;width:0px;border-color:transparent transparent #3385CA;position:absolute;top:-0.71rem;left:0.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li:first-child:hover::before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li:first-child:hover::before{border-color:transparent transparent #0A5EA4}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul::after,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul::after{content:"";position:absolute;z-index:-1;left:0;top:rem-calc(-25px);height:rem-calc(25px);width:100%;transition:all 0.3s cubic-bezier(0.55, 0, 0.1, 1)}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li:hover>ul,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li:hover>ul{transform:translateY(7px);transition:transform 0.4s linear, opacity 0.4s linear, clip 0s 0.2s;opacity:1;clip:rect(-100px, 2000px, 2000px, -100px)}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li.menu_excluir>ul li:first-child::before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li.menu_excluir>ul li:first-child::before{right:auto;left:0.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform textarea{margin:0;resize:vertical;min-height:12.6em;border:0px;font-size:120%;width:100%}.cp.cpe1_old_apagar .dpt-selected .csform textarea:focus{background:#fff}.cp.cpe1_old_apagar .dpt-selected .csform textarea::-webkit-input-placeholder{color:#c70808;opacity:0.6;font-size:80%}.cp.cpe1_old_apagar .dpt-selected .csform textarea:-moz-placeholder{color:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform textarea::-moz-placeholder{color:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform textarea:-ms-input-placeholder{color:#c70808;opacity:0.6}.cp.cpe1_old_apagar .selected{background-color:rgba(255,255,255,0.5)}.cp.cpe1_old_apagar .selected a:hover{color:#16407c !important;font-weight:normal !important}.result-busca-dispositivo,.lista-dispositivo{padding:0 0 1em;min-height:3em}.result-busca-dispositivo ul,.lista-dispositivo ul{list-style:none;margin:0;padding:1em 0 0;transition:all 2s linear;clear:both}.result-busca-dispositivo ul li,.lista-dispositivo ul li{display:table;border-collapse:separate;border-bottom:1px solid white;width:100%}.result-busca-dispositivo ul li.ta_title,.lista-dispositivo ul li.ta_title{background-color:rgba(0,0,0,0.15);border-radius:4px 4px 0 0;width:100%}.result-busca-dispositivo ul li.ta_title span,.lista-dispositivo ul li.ta_title span{padding:0.5em}.result-busca-dispositivo ul li:last-child .itemlabel,.lista-dispositivo ul li:last-child .itemlabel{border-radius:0 0 4px 0px;margin:0px}.result-busca-dispositivo ul li:last-child .iteminput,.lista-dispositivo ul li:last-child .iteminput{border-radius:0 0 0px 4px}.result-busca-dispositivo ul li .iteminput,.lista-dispositivo ul li .iteminput{background-color:rgba(0,0,0,0.1);border-right:1px solid white;display:table-cell;padding:0.5em;vertical-align:middle;text-align:center}.result-busca-dispositivo ul li .iteminput input,.lista-dispositivo ul li .iteminput input{margin:0}.result-busca-dispositivo ul li .itemlabel,.lista-dispositivo ul li .itemlabel{background-color:rgba(0,0,0,0.1);display:table-cell;padding:0.5em;vertical-align:middle;width:100%}.result-busca-dispositivo ul li .itemlabel label,.lista-dispositivo ul li .itemlabel label{line-height:1;font-family:"SourceSansPro", Helvetica, Arial, sans-serif;display:block;margin:0px}.result-busca-dispositivo ul li .itemlabel .artigo,.lista-dispositivo ul li .itemlabel .artigo{float:none}.result-busca-dispositivo .nomenclatura_heranca,.lista-dispositivo .nomenclatura_heranca{font-size:90%;color:#057dba;display:inline}.cp-nav-parents>.dropdown-menu{left:0;right:auto}.cp-nav-parents>.dropdown-menu::before{content:'';position:absolute;top:-11px;width:100%;height:11px}.cp-nav-parents:hover>.dropdown-menu{display:block}.table-notificacoes tbody tr td{border-top:1px solid white;padding:5px;vertical-align:middle}.table-notificacoes tbody tr td ul{margin:0px}.table-notificacoes tbody tr td ul li:hover{background-color:rgba(0,0,0,0.1)}.btn-modal-open{float:right}.class_color_container{background:#ddd !important}.clear{clear:both}.mce-tinymce.mce-container{border:1px solid #ccc !important;margin-right:2px}.mce-btn button:hover{background-color:rgba(0,0,0,0.1) !important;text-shadow:0 0 5px #fff;box-shadow:0 0 5px #777}.mce-menu{background:#eee !important}.displaynone{display:none !important}@media only screen and (max-width: 800px){.cp .fixed{z-index:98;position:relative}.cp.cpe1 .dpt-selected{margin:1em 0}.cp.cpe1 .dpt-selected .csform .actions_parents,.cp.cpe1 .dpt-selected .csform .label_status{font-size:80%;position:static !important;display:block !important;padding:0em;height:auto !important;left:0;right:auto;text-align:left}.cp.cpe1 .dpt-selected .csform .actions_parents div,.cp.cpe1 .dpt-selected .csform .actions_parents li,.cp.cpe1 .dpt-selected .csform .label_status div,.cp.cpe1 .dpt-selected .csform .label_status li{display:inline-block !important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul{transform:translateY(30px);transition:transform 0.1s linear, opacity 0.1s linear, clip 0s 0.3s;clip:rect(0, 0, 0, 0);opacity:0;position:absolute;margin-left:0.5em;box-shadow:0px 6px 18px rgba(0,0,0,0.19),0px 2px 6px rgba(0,0,0,0.23);-webkit-transition-delay:0.4s;transition-delay:0.4s}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li a{border-right:0px !important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li:first-child::before{border-width:0.375rem;border-style:inset inset solid;content:"";display:block;height:0px;width:0px;border-color:transparent transparent #3385CA;position:absolute;top:-0.71rem;left:0.9375rem}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li:first-child:hover::before{border-color:transparent transparent #0A5EA4}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul::after{content:"";position:absolute;z-index:-1;left:0;top:rem-calc(-25px);height:rem-calc(25px);width:100%;transition:all 0.3s cubic-bezier(0.55, 0, 0.1, 1)}.cp.cpe1 .dpt-selected .csform .actions_inserts>li:hover>ul{transform:translateY(7px);transition:transform 0.4s linear, opacity 0.4s linear, clip 0s 0.2s;opacity:1;clip:rect(-100px, 2000px, 2000px, -100px)}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a span{display:none}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-excluir,.cp.cpe1 .cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1_old_apagar .cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar{padding-left:0;min-width:1em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-excluir::before,.cp.cpe1 .cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before,.cp.cpe1_old_apagar .cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar::before{width:100%;margin:0}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in,.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_next,.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior{position:static}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in>ul{left:1em !important;right:1em !important;margin-left:0}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in>ul li:first-child::before{left:37%}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_next>ul{left:0 !important;right:1em !important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior>ul{left:1em !important;right:0 !important;margin-left:0;margin-right:0.5em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child::before{right:42%;left:auto}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{left:10% !important;right:0 !important;margin-left:0;margin-right:0.5em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child::before{right:0;left:auto}}@media print{.cp .vigencias,.toggle-topbar,.menu-icon,.button,.tipo-vigencias,.dne{display:none}#btn_font_menos,#btn_font_mais{display:none}.container{width:100%}} diff --git a/sapl/static/styles/style_tinymce.css b/sapl/static/styles/style_tinymce.css deleted file mode 100644 index d2909b025..000000000 --- a/sapl/static/styles/style_tinymce.css +++ /dev/null @@ -1,8 +0,0 @@ -.mce-content-body { - font-family: "Open Sans" "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; - font-style: normal; - font-weight: normal; - line-height: 1.5; - font-size: 1em; - color: #444444; -} \ No newline at end of file From 0b4aa5d448efe804fbaba41a2434e3880086af02 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Fri, 5 May 2017 11:09:24 -0300 Subject: [PATCH 51/57] =?UTF-8?q?Coloca=20permiss=C3=A3o=20na=20mudan?= =?UTF-8?q?=C3=A7a=20dinamica=20de=20ordena=C3=A7=C3=A3o=20de=20mat=C3=A9r?= =?UTF-8?q?ias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 3bcba074e..47f887c7b 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -2462,12 +2462,13 @@ class AdicionarVariasMateriasOrdemDia(AdicionarVariasMateriasExpediente): @csrf_exempt +@permission_required('sessao.change_expedientemateria', + 'sessao.change_ordemdia') def mudar_ordem_materia_sessao(request): # Pega os dados vindos da requisição posicao_inicial = int(request.POST['pos_ini']) + 1 posicao_final = int(request.POST['pos_fim']) + 1 pk_sessao = int(request.POST['pk_sessao']) - pk_list = request.POST.getlist('pk_list[]') materia = request.POST['materia'] From 7c2907caab2bb59473edd5cb285e3725d2a45f4e Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 5 May 2017 13:08:46 -0300 Subject: [PATCH 52/57] =?UTF-8?q?HOT-FIX:=20conserta=20nome=20de=20vari?= =?UTF-8?q?=C3=A1vel=20errada.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 47f887c7b..852444752 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -2019,7 +2019,7 @@ class VotacaoExpedienteEditView(SessaoPermissionMixin): expediente_id=expediente_id).last() votacao_existente = {'observacao': sub( ' ', ' ', strip_tags(votacao.observacao)), - 'resultado': votacao.tipo_resultado.nome, + 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': votacao.tipo_resultado_votacao_id} context.update({'votacao_titulo': titulo, From 1a400d9ca7d0385550b88d7986524cfeb3fddf4f Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 5 May 2017 14:03:45 -0300 Subject: [PATCH 53/57] Fix bug in bower install --- Dockerfile | 4 +++- requirements/requirements.txt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 64208fe1b..59bee177e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,7 +30,9 @@ RUN pip install -r /var/interlegis/sapl/requirements/requirements.txt --upgrade COPY config/env_dockerfile /var/interlegis/sapl/sapl/.env -RUN python3 manage.py bower install -- --allow-root && \ +# manage.py bower install bug: https://github.com/nvbn/django-bower/issues/51 + +RUN python3 manage.py bower_install -- --allow-root --no-input && \ python3 manage.py collectstatic --no-input && \ rm -rf /var/interlegis/sapl/sapl/.env && \ rm -rf /var/interlegis/sapl/sapl.db diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 6d7592cda..7fd7dbd80 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -15,7 +15,7 @@ django-extra-views==0.8.0 django-filter==0.15.3 django-floppyforms==1.6.2 django-model-utils==2.5 -django-sass-processor==0.4.6 +django-sass-processor==0.5.3 djangorestframework drfdocs easy-thumbnails==2.3 From 9b40b34dd56591536818bb002be67de0a873b586 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 5 May 2017 14:20:44 -0300 Subject: [PATCH 54/57] Pick from sapl latest --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index cd899e6c4..50bdf6512 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ sapldb: ports: - "5532:5432" sapl: - build: . + image: interlegis/sapl:latest volumes: - sapl_data:/var/interlegis/sapl/data - sapl_media:/var/interlegis/sapl/media From ce0d0ff6e9232011c7f191d928dd324e0421e6fa Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 8 May 2017 15:56:22 -0300 Subject: [PATCH 55/57] Muda jeito e pegar ultimo valor do model Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 6ab3cd184..0d2f5be10 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -130,9 +130,7 @@ def get_fk_related(field, value, label=None): if not field.null: fields_dict = get_fields_dict(field.related_model) # Cria stub ao final da tabela para evitar erros - pk = 1 - if hasattr(field.related_model.objects.last(), 'pk'): - pk = field.related_model.objects.last().pk + pk = get_last_value(field.related_model) with reversion.create_revision(): reversion.set_comment('Stub criado pela migração') value = mommy.make( From 30b61d9f84cd6ea651e56a69ae8cb54bb9b01a30 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 8 May 2017 16:01:44 -0300 Subject: [PATCH 56/57] Adiciona colunas no script sql Signed-off-by: Luciano Almeida --- sapl/legacy/scripts/fix_tables.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql index 479a2ed5e..ed93373b1 100644 --- a/sapl/legacy/scripts/fix_tables.sql +++ b/sapl/legacy/scripts/fix_tables.sql @@ -2,15 +2,19 @@ SELECT REPLACE(@@sql_mode,'STRICT_TRANS_TABLES,',''); -- Exclui procedures caso já existam DROP PROCEDURE IF EXISTS verifica_campos_proposicao; +DROP PROCEDURE IF EXISTS verifica_campos_tipo_materia_legislativa; DROP PROCEDURE IF EXISTS verifica_campos_sessao_plenaria_presenca; DROP PROCEDURE IF EXISTS cria_lexml_registro_provedor_e_publicador; -- Procedure para criar campo num_proposicao em proposicao CREATE PROCEDURE verifica_campos_proposicao() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='proposicao' AND column_name='num_proposicao') THEN ALTER TABLE proposicao ADD COLUMN num_proposicao INT(11) NULL after txt_justif_devolucao; END IF; END; +-- Procedure para criar campo iind_num_automatica em tipo_materia_legislativa +CREATE PROCEDURE verifica_campos_tipo_materia_legislativa() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='tipo_materia_legislativa' AND column_name='ind_num_automatica') THEN ALTER TABLE tipo_materia_legislativa ADD COLUMN ind_num_automatica BOOLEAN NULL DEFAULT FALSE after des_tipo_materia; END IF; IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='tipo_materia_legislativa' AND column_name='quorum_minimo_votacao') THEN ALTER TABLE tipo_materia_legislativa ADD COLUMN quorum_minimo_votacao INT(11) NULL after ind_num_automatica; END IF; END; -- Procedure para criar campos cod_presenca_sessao (sendo a nova PK da tabela) e dat_sessao em sessao_plenaria_presenca CREATE PROCEDURE verifica_campos_sessao_plenaria_presenca() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='sessao_plenaria_presenca' AND column_name='cod_presenca_sessao') THEN ALTER TABLE sessao_plenaria_presenca DROP PRIMARY KEY, ADD cod_presenca_sessao INT AUTO_INCREMENT PRIMARY KEY FIRST; END IF; IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='sessao_plenaria_presenca' AND column_name='dat_sessao') THEN ALTER TABLE sessao_plenaria_presenca ADD COLUMN dat_sessao DATE NULL after cod_parlamentar; END IF; END; -- Procedure para criar tabela lexml_registro_provedor e lexml_registro_publicador CREATE PROCEDURE cria_lexml_registro_provedor_e_publicador() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='lexml_registro_publicador') THEN CREATE TABLE lexml_registro_publicador (cod_publicador INT AUTO_INCREMENT NOT NULL, id_publicador INT, nom_publicador VARCHAR(255), adm_email VARCHAR(50), sigla VARCHAR(255), nom_responsavel VARCHAR(255), tipo VARCHAR(50), id_responsavel INT, PRIMARY KEY (cod_publicador)); END IF; IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='lexml_registro_provedor') THEN CREATE TABLE lexml_registro_provedor (cod_provedor INT AUTO_INCREMENT NOT NULL, id_provedor INT, nom_provedor VARCHAR(255), sgl_provedor VARCHAR(15), adm_email VARCHAR(50), nom_responsavel VARCHAR(255), tipo VARCHAR(50), id_responsavel INT, xml_provedor LONGTEXT, PRIMARY KEY (cod_provedor)); END IF; END; -- Executa as procedures criadas acima CALL verifica_campos_proposicao; +CALL verifica_campos_tipo_materia_legislativa; CALL verifica_campos_sessao_plenaria_presenca; CALL cria_lexml_registro_provedor_e_publicador; From ef4441d4e394e4a8946f1f6a256e202567259491 Mon Sep 17 00:00:00 2001 From: eduardocalil Date: Tue, 9 May 2017 12:53:36 -0300 Subject: [PATCH 57/57] Fix #1056 (#1059) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #1056 * Retira try-except desnecessário --- sapl/parlamentares/views.py | 43 +++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index d703e1c2c..afbe80ed0 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -1,7 +1,7 @@ from django.contrib import messages -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.core.urlresolvers import reverse, reverse_lazy -from django.db.models import F +from django.db.models import F, Q from django.http.response import HttpResponseRedirect from django.utils.datastructures import MultiValueDictKeyError from django.utils.translation import ugettext_lazy as _ @@ -344,8 +344,47 @@ class ParlamentarCrud(Crud): # Tira Link do avatar_html e coloca no nome for row in context['rows']: + # Coloca a filiação atual ao invés da última + if row[0][1]: + # Pega o Parlamentar por meio da pk + parlamentar = Parlamentar.objects.get( + id=(row[0][1].split('/')[-1])) + + # Pega a Legislatura + legislatura = Legislatura.objects.get( + id=context['legislatura_id']) + + # As condições para mostrar a filiação são: + # A data de filiacao deve ser menor que a data de fim + # da legislatura e data de desfiliação deve nula, ou maior, + # ou igual a data de fim da legislatura + try: + filiacao = parlamentar.filiacao_set.get(Q( + data__lte=legislatura.data_fim, + data_desfiliacao__gte=legislatura.data_fim) | Q( + data__lte=legislatura.data_fim, + data_desfiliacao__isnull=True)) + + # Caso não exista filiação com essas condições + except ObjectDoesNotExist: + row[2] = ('Não possui filiação', None) + + # Caso exista mais de uma filiação nesse intervalo + # Entretanto, NÃO DEVE OCORRER + except MultipleObjectsReturned: + filiacao = parlamentar.filiacao_set.filter(Q( + data__lte=legislatura.data_fim, + data_desfiliacao__gte=legislatura.data_fim) | Q( + data__lte=legislatura.data_fim, + data_desfiliacao__isnull=True)).last() + + # Caso encontre UMA filiação nessas condições + else: + row[2] = (filiacao.partido.sigla, None) + row[1] = (row[1][0], row[0][1]) row[0] = (row[0][0], None) + return context