diff --git a/requirements/requirements.txt b/requirements/requirements.txt index bc7c9fd81..f8ad43383 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -9,8 +9,6 @@ django-contrib-postgres==0.0.1 django-floppyforms==1.8.0 django-extra-views==0.12.0 django-model-utils==3.1.2 -django-reversion==3.0.2 -django-reversion-compare==0.8.6 django-speedinfo==1.4.0 django-extensions==2.1.4 django-image-cropping==1.2 diff --git a/sapl/audiencia/models.py b/sapl/audiencia/models.py index 234171e14..d74f0b6e3 100755 --- a/sapl/audiencia/models.py +++ b/sapl/audiencia/models.py @@ -1,4 +1,3 @@ -import reversion from django.db import models from django.utils import timezone from django.utils.translation import ugettext_lazy as _ @@ -29,7 +28,6 @@ def anexo_upload_path(instance, filename): instance, filename, subpath='anexo', pk_first=True) -@reversion.register() class TipoAudienciaPublica(models.Model): TIPO_AUDIENCIA_CHOICES = Choices(('A', 'audiencia', _('Audiência Pública')), ('P', 'plebiscito', _('Plebiscito')), @@ -51,7 +49,6 @@ class TipoAudienciaPublica(models.Model): return self.nome -@reversion.register() class AudienciaPublica(models.Model): materia = models.ForeignKey( MateriaLegislativa, @@ -175,7 +172,6 @@ class AudienciaPublica(models.Model): update_fields=update_fields) -@reversion.register() class AnexoAudienciaPublica(models.Model): audiencia = models.ForeignKey(AudienciaPublica, on_delete=models.PROTECT) diff --git a/sapl/base/admin.py b/sapl/base/admin.py index 46ab77bf3..c7df7ca63 100644 --- a/sapl/base/admin.py +++ b/sapl/base/admin.py @@ -1,7 +1,6 @@ from django.contrib import admin from django.shortcuts import redirect from django.utils.translation import ugettext_lazy as _ -from reversion.models import Revision from sapl.base.models import AuditLog from sapl.utils import register_all_models_in_admin @@ -12,18 +11,6 @@ admin.site.site_title = 'Administração - SAPL' admin.site.site_header = 'Administração - SAPL' -class RevisionAdmin(admin.ModelAdmin): - list_display = ('user', 'comment', 'date_created') - search_fields = ('=user__username', '=user__email') - date_hierarchy = ('date_created') - - def change_view(self, request, obj=None): - self.message_user(request, _('You cannot change history.')) - return redirect('admin:reversion_revision_changelist') - -admin.site.register(Revision, RevisionAdmin) - - class AuditLogAdmin(admin.ModelAdmin): pass diff --git a/sapl/base/legacy.yaml b/sapl/base/legacy.yaml deleted file mode 100644 index 2d866226e..000000000 --- a/sapl/base/legacy.yaml +++ /dev/null @@ -1,7 +0,0 @@ -TipoAutor: - descricao: des_tipo_autor - -Autor: - nome: nom_autor - cargo: des_cargo - tipo: tip_autor diff --git a/sapl/base/migrations/0052_auto_20220914_1125.py b/sapl/base/migrations/0052_auto_20220914_1125.py new file mode 100644 index 000000000..734391dbc --- /dev/null +++ b/sapl/base/migrations/0052_auto_20220914_1125.py @@ -0,0 +1,15 @@ +# Generated by Django 2.2.28 on 2022-09-14 14:25 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0051_auto_20220814_2138'), + ] + + operations = [ + migrations.RunSQL("DROP TABLE IF EXISTS reversion_version"), + migrations.RunSQL("DROP TABLE IF EXISTS reversion_revision"), + ] diff --git a/sapl/base/models.py b/sapl/base/models.py index dda6ae48b..f6bec5faf 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -8,7 +8,6 @@ from django.db.models.deletion import CASCADE from django.db.models.signals import post_migrate from django.db.utils import DEFAULT_DB_ALIAS from django.utils.translation import ugettext_lazy as _ -import reversion from sapl.utils import (LISTA_DE_UFS, YES_NO_CHOICES, get_settings_auth_user_model, models_with_gr_for_model) @@ -42,7 +41,6 @@ ASSINATURA_ATA_CHOICES = ( ) -@reversion.register() class CasaLegislativa(models.Model): # TODO ajustar todos os max_length !!!! # cod_casa => id (pk) @@ -85,7 +83,6 @@ class CasaLegislativa(models.Model): 'municipio': self.municipio} -@reversion.register() class AppConfig(models.Model): POLITICA_PROTOCOLO_CHOICES = ( @@ -298,7 +295,6 @@ class AppConfig(models.Model): 'id': self.id} -@reversion.register() class TipoAutor(models.Model): descricao = models.CharField( max_length=50, @@ -323,7 +319,6 @@ class TipoAutor(models.Model): return self.descricao -@reversion.register() class Autor(models.Model): operadores = models.ManyToManyField( get_settings_auth_user_model(), diff --git a/sapl/comissoes/legacy.yaml b/sapl/comissoes/legacy.yaml deleted file mode 100644 index 8e1040510..000000000 --- a/sapl/comissoes/legacy.yaml +++ /dev/null @@ -1,51 +0,0 @@ -TipoComissao: - dispositivo_regimental: des_dispositivo_regimental - natureza: sgl_natureza_comissao - nome: nom_tipo_comissao - sigla: sgl_tipo_comissao - -Comissao: - agenda_reuniao: des_agenda_reuniao - apelido_temp: nom_apelido_temp - data_criacao: dat_criacao - data_extincao: dat_extincao - data_fim_comissao: dat_fim_comissao - data_final_prevista_temp: dat_final_prevista_temp - data_instalacao_temp: dat_instalacao_temp - data_prorrogada_temp: dat_prorrogada_temp - email: end_email - endereco_secretaria: end_secretaria - fax_secretaria: num_fax_secretaria - finalidade: txt_finalidade - local_reuniao: loc_reuniao - nome: nom_comissao - secretario: nom_secretario - sigla: sgl_comissao - telefone_reuniao: num_tel_reuniao - telefone_secretaria: num_tel_secretaria - tipo: tip_comissao - unidade_deliberativa: ind_unid_deliberativa - -Periodo (PeriodoCompComissao): - data_fim: dat_fim_periodo - data_inicio: dat_inicio_periodo - -CargoComissao: - nome: des_cargo - unico: ind_unico - -Participacao (ComposicaoComissao): - cargo: cod_cargo - data_designacao: dat_designacao - data_desligamento: dat_desligamento - motivo_desligamento: des_motivo_desligamento - observacao: obs_composicao - parlamentar: cod_parlamentar - titular: ind_titular - -Reuniao (ReuniaoComissao): - comissao: cod_comissao - numero: num_reuniao - data: dat_inicio_reuniao - observacao: txt_observacao - diff --git a/sapl/comissoes/models.py b/sapl/comissoes/models.py index a3f632a43..5c6a67d8a 100644 --- a/sapl/comissoes/models.py +++ b/sapl/comissoes/models.py @@ -1,4 +1,3 @@ -import reversion from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices @@ -10,7 +9,6 @@ from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation, OverwriteStorage) -@reversion.register() class TipoComissao(models.Model): NATUREZA_CHOICES = Choices(('T', 'temporaria', _('Temporária')), ('P', 'permanente', _('Permanente'))) @@ -32,7 +30,6 @@ class TipoComissao(models.Model): return self.nome -@reversion.register() class Comissao(models.Model): tipo = models.ForeignKey(TipoComissao, on_delete=models.PROTECT, @@ -99,7 +96,6 @@ class Comissao(models.Model): return self.sigla + ' - ' + self.nome -@reversion.register() class Periodo(models.Model): # PeriodoCompComissao data_inicio = models.DateField(verbose_name=_('Data Início')) data_fim = models.DateField( @@ -120,7 +116,6 @@ class Periodo(models.Model): # PeriodoCompComissao return '-' -@reversion.register() class CargoComissao(models.Model): id_ordenacao = models.PositiveIntegerField( blank=True, null=True, verbose_name=_('Posição na Ordenação'), @@ -139,7 +134,6 @@ class CargoComissao(models.Model): return self.nome -@reversion.register() class Composicao(models.Model): # IGNORE comissao = models.ForeignKey(Comissao, on_delete=models.CASCADE, @@ -157,7 +151,6 @@ class Composicao(models.Model): # IGNORE return '%s: %s' % (self.comissao.sigla, self.periodo) -@reversion.register() class Participacao(models.Model): # ComposicaoComissao composicao = models.ForeignKey(Composicao, related_name='participacao_set', @@ -314,7 +307,6 @@ class Reuniao(models.Model): update_fields=update_fields) -@reversion.register() class DocumentoAcessorio(models.Model): reuniao = models.ForeignKey(Reuniao, related_name='documentoacessorio_set', diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index 4cb452d4d..783e28ce0 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -12,7 +12,6 @@ from django.utils.decorators import classonlymethod from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ from image_cropping.fields import ImageCropField, ImageRatioField -import reversion from sapl.compilacao.utils import (get_integrations_view_names, int_to_letter, int_to_roman) @@ -20,7 +19,6 @@ from sapl.utils import YES_NO_CHOICES, get_settings_auth_user_model,\ texto_upload_path, restringe_tipos_de_arquivo_img -@reversion.register() class TimestampedMixin(models.Model): created = models.DateTimeField( verbose_name=_('created'), @@ -32,7 +30,6 @@ class TimestampedMixin(models.Model): abstract = True -@reversion.register() class BaseModel(models.Model): class Meta: @@ -87,7 +84,6 @@ class BaseModel(models.Model): update_fields=update_fields) -@reversion.register() class PerfilEstruturalTextoArticulado(BaseModel): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -121,7 +117,6 @@ class PerfilEstruturalTextoArticulado(BaseModel): return parents -@reversion.register() class TipoTextoArticulado(models.Model): sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -190,7 +185,6 @@ PRIVACIDADE_STATUS = ( ) -@reversion.register() class TextoArticulado(TimestampedMixin): data = models.DateField( blank=True, @@ -564,7 +558,6 @@ class TextoArticulado(TimestampedMixin): update(dpk) -@reversion.register() class TipoNota(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -581,7 +574,6 @@ class TipoNota(models.Model): return '%s: %s' % (self.sigla, self.nome) -@reversion.register() class TipoVide(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -596,7 +588,6 @@ class TipoVide(models.Model): return '%s: %s' % (self.sigla, self.nome) -@reversion.register() class TipoDispositivo(BaseModel): """ - no attributo rotulo_prefixo_texto, caso haja um ';' (ponto e vírgula), e @@ -806,7 +797,6 @@ class TipoDispositivo(BaseModel): return False -@reversion.register() class TipoDispositivoRelationship(BaseModel): pai = models.ForeignKey( TipoDispositivo, @@ -855,7 +845,6 @@ class TipoDispositivoRelationship(BaseModel): self.filho_permitido.nome if self.filho_permitido else '') -@reversion.register() class TipoPublicacao(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -870,7 +859,6 @@ class TipoPublicacao(models.Model): return self.nome -@reversion.register() class VeiculoPublicacao(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -885,7 +873,6 @@ class VeiculoPublicacao(models.Model): return '%s: %s' % (self.sigla, self.nome) -@reversion.register() class Publicacao(TimestampedMixin): ta = models.ForeignKey( TextoArticulado, @@ -965,7 +952,6 @@ def imagem_upload_path(instance, filename): return texto_upload_path(instance, filename, subpath='') -@reversion.register() class Dispositivo(BaseModel, TimestampedMixin): TEXTO_PADRAO_DISPOSITIVO_REVOGADO = force_text(_('(Revogado)')) INTERVALO_ORDEM = 1000 @@ -1907,7 +1893,6 @@ class Dispositivo(BaseModel, TimestampedMixin): ordem_bloco_atualizador=count) -@reversion.register() class Vide(TimestampedMixin): texto = models.TextField(verbose_name=_('Texto do Vide')) @@ -1954,7 +1939,6 @@ NOTAS_PUBLICIDADE_CHOICES = ( ) -@reversion.register() class Nota(TimestampedMixin): NPRIV = 1 diff --git a/sapl/legacy/Docs/verificação verbose names.txt b/sapl/legacy/Docs/verificação verbose names.txt deleted file mode 100644 index 6ee51676f..000000000 --- a/sapl/legacy/Docs/verificação verbose names.txt +++ /dev/null @@ -1,68 +0,0 @@ --> /sapl/comissoes/models.py - #1 - class ComposicaoComissao: Verificar comissao e periodo_comp. - --> /sapl/lexml/models.py - #1 - Na classe 'LexmlRegistroProvedor', 'sigla_provedor' e 'tipo' não tem no html - #2 - Na classe 'LexmlRegistroProvedor' falta o campo 'Endereço do provedor OAI' - #3 - Na classe 'LexmlRegistroPublicador' 'tipo' não tem no html - --> /sapl/norma/models.py - ## html's faltando: - VinculoNormaJuridica - - #1 - Na classe 'LegislacaoCitada' falta 'Tipo Norma', 'Número' e 'Ano' - #2 - Na classe 'NormaJuridica' falta os campos 'Matéria Legislativa', 'Texto original (PDF)' e 'Situação de Vigência' - --> /sapl/parlamentares/models.py - ## html's faltando: - Localidade(Não tem html mesmo) - ComposicaoMesa - ComposicaoColigacao(Talvez seja http://sapl3.interlegis.leg.br/cadastros/auxiliares/coligacao/coligacao_index_html) - - #1 - Classe 'Legislatura' falta 'Nº Legislatura' - #2 - Na classe 'Parlamentar' faltam os campos 'Observação', 'UF' e 'Login' - #3 - Na classe 'Mandato' eu não tenho certeza se os campos 'tipo_afastamento' e 'tipo_causa_fim_mandato' - # correspondem aos campos 'Natureza do Mandato' e 'Expedição do Diploma', então naõ adicionei os verbose_name - --> /sapl/protocoloadm/models.py - #1 - Na classe 'DocumentoAdministrativo' não possui o campo 'Autor' no html por isso está sem verbose_name e falta o - campo 'Texto Integral' na classe. - #2 - Na classe 'StatusTramitacaoAdministrativo' falta o campo 'Indicador de Tramitação' - #3 - A classe protocolo tá bastante diferente do html - - Ver depois - --> /sapl/materia/models.py - ## html's faltando: - AcompMateria - AssuntoMateria - DespachoInicial - MateriaAssunto - Parecer - - #1 - Na classe 'MateriaLegislativa' falta o campo 'cep' - #2 - Na classe 'Anexada' faltam os campos 'Tipo', 'Número' e 'Ano' - #3 - Na classe 'TipoAutor' falta o campo 'Tipo' - #4 - Classe 'Autor' com campos a mais - #5 - Na classe 'Autoria' faltam os campos 'Tipo de Autor' e 'Nome Autor' - #6 - Na classe 'DocumentoAcessorio' faltam os campos 'Texto digitalizado (PDF)' e 'Obeservação' - #7 - Classe 'Proposicao' muito diferente do html - #8 - Na classe 'StatusTramitacao', 'fim_tramitacao' e 'retorno_tramitacao' não deveriam tá separados - #9 - Na classe 'UnidadeTramitacao' falta o campo 'Correspondente SPDO' - --> /sapl/sessao/models.py - ## html's faltando: - SessaoPlenariaPresenca - RegistroVotacaoParlamentar - OrdemDiaPresenca - MesaSessaoPlenaria - ExpedienteSessaoPlenaria - - #1 - Na classe 'SessaoPlenaria' faltam os campos de arquivos indexados - #2 - Na classe 'ExpedienteMateria' faltam os campos 'Tipo da Sessão', 'Tipo Matéria', 'Núm. Matéria' e 'Ano Matéria' - #3 - Na Classe 'Oradores' faltam os campos 'Parlamentar' e 'Discurso' - #4 - Na Classe 'OradoresExpediente' faltam os campos 'Parlamentar' e 'Discurso' - ***** As páginas 'Oradores' e 'OradoresExpediente' são iguas - #5 - Na classe 'OrdemDia' faltam os campos 'Tipo da Sessão', 'Tipo Matéria', 'Núm. Matéria' e 'Ano Matéria' - ***** As páginas 'ExpedienteMateria' e 'OrdemDia' são iguas - #6 - Na classe 'RegistroVotacao' faltam os campos 'Não Votou:', 'Anular Votação' e - 'A totalização inclui o voto do Presidente?' diff --git a/sapl/legacy/__init__.py b/sapl/legacy/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/sapl/legacy/admin.py b/sapl/legacy/admin.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/sapl/legacy/management/__init__.py b/sapl/legacy/management/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/sapl/legacy/management/commands/__init__.py b/sapl/legacy/management/commands/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/sapl/legacy/management/commands/migracao_25_31.py b/sapl/legacy/management/commands/migracao_25_31.py deleted file mode 100644 index ba9a80224..000000000 --- a/sapl/legacy/management/commands/migracao_25_31.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.core.management.base import BaseCommand - -from sapl.legacy.migracao import migrar - - -class Command(BaseCommand): - - help = 'Migração de dados do SAPL 2.5 para o SAPL 3.1' - - def add_arguments(self, parser): - parser.add_argument( - '-a', - action='store_true', - default=False, - dest='apagar_do_legado', - help='Apagar entradas migradas do legado', - ) - - def handle(self, *args, **options): - migrar(apagar_do_legado=options['apagar_do_legado']) diff --git a/sapl/legacy/management/commands/migracao_documentos.py b/sapl/legacy/management/commands/migracao_documentos.py deleted file mode 100644 index 7cba09d5a..000000000 --- a/sapl/legacy/management/commands/migracao_documentos.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.core.management.base import BaseCommand - -from sapl.legacy.migracao_documentos import migrar_documentos - - -class Command(BaseCommand): - - help = 'Migração documentos do SAPL 2.5 para o SAPL 3.1' - - def handle(self, *args, **options): - migrar_documentos() diff --git a/sapl/legacy/management/commands/ressuscitar_deps.py b/sapl/legacy/management/commands/ressuscitar_deps.py deleted file mode 100644 index ea219330c..000000000 --- a/sapl/legacy/management/commands/ressuscitar_deps.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.core.management.base import BaseCommand - -from sapl.legacy.scripts.ressuscita_dependencias import adiciona_ressuscitar - - -class Command(BaseCommand): - - help = 'Ressuscita dependências apagadas ' \ - 'que são necessárias para migrar outros registros' - - def handle(self, *args, **options): - adiciona_ressuscitar() diff --git a/sapl/legacy/migracao.py b/sapl/legacy/migracao.py deleted file mode 100644 index 94fd25930..000000000 --- a/sapl/legacy/migracao.py +++ /dev/null @@ -1,82 +0,0 @@ -import subprocess -from getpass import getpass - -import requests -from django.core import management -from unipath import Path - -from sapl.legacy.migracao_dados import (REPO, TAG_MARCO, gravar_marco, info, - migrar_dados) -from sapl.legacy.migracao_documentos import migrar_documentos -from sapl.legacy.migracao_usuarios import migrar_usuarios -from sapl.legacy.scripts.exporta_zope.variaveis_comuns import TAG_ZOPE -from sapl.legacy_migration_settings import DIR_REPO, NOME_BANCO_LEGADO -from sapl.materia.models import Proposicao - - -def adornar_msg(msg): - return '\n{1}\n{0}\n{1}'.format(msg, '#' * len(msg)) - - -def migrar(apagar_do_legado=False): - if TAG_MARCO in REPO.tags: - info('A migração já está feita.') - return - assert TAG_ZOPE in REPO.tags, adornar_msg( - 'Antes de migrar ' - 'é necessário fazer a exportação de documentos do zope') - management.call_command('migrate') - migrar_dados(apagar_do_legado) - migrar_usuarios(REPO.working_dir) - migrar_documentos(REPO) - gravar_marco() - # compactar_media() - - -def compactar_media(): - - # tar de media/sapl - print('Criando tar de media... ', end='', flush=True) - arq_tar = DIR_REPO.child('{}.media.tar'.format(NOME_BANCO_LEGADO)) - arq_tar.remove() - subprocess.check_output(['tar', 'cfh', arq_tar, '-C', DIR_REPO, 'sapl']) - print('SUCESSO') - - -PROPOSICAO_UPLOAD_TO = Proposicao._meta.get_field('texto_original').upload_to - - -def salva_conteudo_do_sde(proposicao, conteudo): - caminho_relativo = PROPOSICAO_UPLOAD_TO( - proposicao, 'proposicao_sde_{}.xml'.format(proposicao.pk)) - caminho_absoluto = Path(REPO.working_dir, caminho_relativo) - caminho_absoluto.parent.mkdir(parents=True) - # ajusta caminhos para folhas de estilo - conteudo = conteudo.replace(b'"XSLT/HTML', b'"/XSLT/HTML') - conteudo = conteudo.replace(b"'XSLT/HTML", b"'/XSLT/HTML") - with open(caminho_absoluto, 'wb') as arq: - arq.write(conteudo) - proposicao.texto_original = caminho_relativo - proposicao.save() - - -def scrap_sde(url, usuario, senha=None): - if not senha: - senha = getpass() - - # login - session = requests.session() - res = session.post('{}?retry=1'.format(url), - {'__ac_name': usuario, '__ac_password': senha}) - assert res.status_code == 200 - - url_proposicao_tmpl = '{}/sapl_documentos/proposicao/{}/renderXML?xsl=__default__' # noqa - total = Proposicao.objects.count() - for num, proposicao in enumerate(Proposicao.objects.all()): - pk = proposicao.pk - url_proposicao = url_proposicao_tmpl.format(url, pk) - res = session.get(url_proposicao) - print("pk: {} status: {} {} (progresso: {:.2%})".format( - pk, res.status_code, url_proposicao, num / total)) - if res.status_code == 200: - salva_conteudo_do_sde(proposicao, res.content) diff --git a/sapl/legacy/migracao_dados.py b/sapl/legacy/migracao_dados.py deleted file mode 100644 index 46e1fa7cf..000000000 --- a/sapl/legacy/migracao_dados.py +++ /dev/null @@ -1,1473 +0,0 @@ -import datetime -import os -import re -import subprocess -import traceback -from collections import OrderedDict, defaultdict, namedtuple -from datetime import date -from functools import lru_cache, partial -from itertools import groupby -from operator import xor - -import git -import pkg_resources -import pyaml -import pytz -import reversion -import yaml -from bs4 import BeautifulSoup -from django.apps import apps -from django.contrib.auth import get_user_model -from django.contrib.auth.models import Group -from django.contrib.contenttypes.models import ContentType -from django.core.exceptions import ObjectDoesNotExist -from django.core.management.commands.flush import Command as FlushCommand -from django.db import connections, transaction -from django.db.models import Max, Q -from pyaml import UnsafePrettyYAMLDumper -from unipath import Path - -from sapl.base.models import AppConfig as AppConf -from sapl.base.models import Autor, TipoAutor, cria_models_tipo_autor -from sapl.comissoes.models import Comissao, Composicao, Participacao, Reuniao -from sapl.legacy.models import NormaJuridica as OldNormaJuridica -from sapl.legacy.models import TipoNumeracaoProtocolo -from sapl.legacy_migration_settings import (DIR_DADOS_MIGRACAO, DIR_REPO, - NOME_BANCO_LEGADO, PYTZ_TIMEZONE, - SIGLA_CASA) -from sapl.materia.models import (AcompanhamentoMateria, DocumentoAcessorio, - MateriaLegislativa, Proposicao, - StatusTramitacao, TipoDocumento, - TipoMateriaLegislativa, TipoProposicao, - Tramitacao) -from sapl.norma.models import (AssuntoNorma, NormaJuridica, NormaRelacionada, - TipoVinculoNormaJuridica) -from sapl.parlamentares.models import (Legislatura, Mandato, Parlamentar, - Partido, TipoAfastamento) -from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, - StatusTramitacaoAdministrativo) -from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao, OrdemDia, - RegistroVotacao, TipoResultadoVotacao) -from sapl.utils import normalize - -from .scripts.normaliza_dump_mysql import normaliza_dump_mysql - - -# YAML SETUP ############################################################### -def dict_representer(dumper, data): - return dumper.represent_dict(data.items()) - -yaml.add_representer(OrderedDict, dict_representer) - - -# importante para preservar a ordem ao ler yaml no python 3.5 -def dict_constructor(loader, node): - return OrderedDict(loader.construct_pairs(node)) - -yaml.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, - dict_constructor) - -# BASE ###################################################################### -# apps to be migrated, in app dependency order (very important) -appconfs = [apps.get_app_config(n) for n in [ - 'parlamentares', - 'comissoes', - # base precisa vir depois dos apps parlamentares e comissoes - # pois Autor os referencia - 'base', - 'materia', - 'norma', - 'sessao', - 'lexml', - 'protocoloadm', ]] - -unique_constraints = [] -one_to_one_constraints = [] -primeira_vez = [] - -# apps quase não têm interseção -name_sets = [(ac.label, set(m.__name__ for m in ac.get_models())) - for ac in appconfs] -for a1, s1 in name_sets: - for a2, s2 in name_sets: - if a1 is not a2: - # existe uma interseção de nomes entre comissoes e materia - if {a1, a2} == {'comissoes', 'materia'}: - assert s1.intersection(s2) == {'DocumentoAcessorio'} - else: - assert not s1.intersection(s2) - - -# RENAMES ################################################################### - -MODEL_RENAME_PATTERN = re.compile('(.+) \((.+)\)') -MODEL_RENAME_INCLUDE_PATTERN = re.compile('<(.+)>') - - -def get_renames(): - field_renames = {} - model_renames = {} - includes = {} - for app in appconfs: - app_rename_data = yaml.load( - pkg_resources.resource_string(app.module.__name__, 'legacy.yaml'), - yaml.Loader - ) - for model_name, renames in app_rename_data.items(): - # armazena ou substitui includes - if MODEL_RENAME_INCLUDE_PATTERN.match(model_name): - includes[model_name] = renames - continue - elif isinstance(renames, str): - renames = includes[renames] - # detecta mudança de nome - match = MODEL_RENAME_PATTERN.match(model_name) - if match: - model_name, old_name = match.groups() - else: - old_name = None - model = app.get_model(model_name) - if old_name: - model_renames[model] = old_name - field_renames[model] = renames - - return field_renames, model_renames - - -field_renames, model_renames = get_renames() -legacy_app = apps.get_app_config('legacy') -models_novos_para_antigos = { - model: legacy_app.get_model(model_renames.get(model, model.__name__)) - for model in field_renames} -models_novos_para_antigos[Composicao] = models_novos_para_antigos[Participacao] - -campos_novos_para_antigos = { - model._meta.get_field(nome_novo): nome_antigo - for model, renames in field_renames.items() - for nome_novo, nome_antigo in renames.items()} - -# campos de Composicao (de Comissao) -for nome_novo, nome_antigo in (('comissao', 'cod_comissao'), - ('periodo', 'cod_periodo_comp')): - campos_novos_para_antigos[ - Composicao._meta.get_field(nome_novo)] = nome_antigo - - -# campos virtuais de Proposicao para funcionar com get_fk_related -class CampoVirtual(namedtuple('CampoVirtual', 'model related_model')): - null = True - - -CAMPOS_VIRTUAIS_PROPOSICAO = { - TipoMateriaLegislativa: CampoVirtual(Proposicao, MateriaLegislativa), - TipoDocumento: CampoVirtual(Proposicao, DocumentoAcessorio) -} -for campo_virtual in CAMPOS_VIRTUAIS_PROPOSICAO.values(): - campos_novos_para_antigos[campo_virtual] = 'cod_mat_ou_doc' - - -CAMPOS_VIRTUAIS_TIPO_PROPOSICAO = { - 'M': CampoVirtual(TipoProposicao, TipoMateriaLegislativa), - 'D': CampoVirtual(TipoProposicao, TipoDocumento) -} -for campo_virtual in CAMPOS_VIRTUAIS_TIPO_PROPOSICAO.values(): - campos_novos_para_antigos[campo_virtual] = 'tip_mat_ou_doc' - - -# campos virtuais de Autor para funcionar com get_fk_related -CAMPOS_VIRTUAIS_AUTOR = {related: CampoVirtual(Autor, related) - for related in (Parlamentar, Comissao, Partido)} -for related, campo_antigo in [(Parlamentar, 'cod_parlamentar'), - (Comissao, 'cod_comissao'), - (Partido, 'cod_partido')]: - campo_virtual = CAMPOS_VIRTUAIS_AUTOR[related] - campos_novos_para_antigos[campo_virtual] = campo_antigo - - -# MIGRATION ################################################################# - - -def info(msg): - print('INFO: ' + msg) - - -ocorrencias = defaultdict(list) - - -def warn(tipo, msg, dados): - ocorrencias[tipo].append(dados) - print('CUIDADO! ' + msg.format(**dados)) - - -@lru_cache() -def get_pk_legado(tabela): - if tabela == 'despacho_inicial': - # adaptação para deleção correta no mysql ao final de migrar_model - # acompanha o agrupamento de despacho_inicial feito em iter_sql_records - return 'cod_materia', 'cod_comissao' - res = exec_legado( - 'show index from {} WHERE Key_name = "PRIMARY"'.format(tabela)) - return [r[4] for r in res] - - -@lru_cache() -def get_estrutura_legado(model): - model_legado = models_novos_para_antigos[model] - tabela_legado = model_legado._meta.db_table - campos_pk_legado = get_pk_legado(tabela_legado) - return model_legado, tabela_legado, campos_pk_legado - - -def com_aspas_se_necessario(valor): - if isinstance(valor, int): - return valor - else: - return '"{}"'.format(valor) - - -class ForeignKeyFaltando(ObjectDoesNotExist): - 'Uma FK aponta para um registro inexistente' - - def __init__(self, field, valor, old): - self.field = field - self.valor = valor - self.old = old - - msg = 'FK não encontrada para [{campo} = {valor}] (em {tabela} / pk = {pk})' # noqa - - @property - def dados(self): - campo = campos_novos_para_antigos[self.field] - _, tabela, campos_pk = get_estrutura_legado(self.field.model) - pk = {c: getattr(self.old, c) for c in campos_pk} - sql = 'select * from {} where {};'.format( - tabela, - ' and '.join([ - '{} = {}'.format(k, com_aspas_se_necessario(v)) - for k, v in pk.items()])) - return OrderedDict((('campo', campo), - ('valor', self.valor), - ('tabela', tabela), - ('pk', pk), - ('sql', sql))) - - -@lru_cache() -def _get_all_ids_from_model(model): - # esta função para uso apenas em get_fk_related - return set(model.objects.values_list('id', flat=True)) - - -def get_fk_related(field, old): - valor = getattr(old, campos_novos_para_antigos[field]) - if valor is None and field.null: - return None - if valor in _get_all_ids_from_model(field.related_model): - return valor - elif valor == 0 and field.null: - # consideramos zeros como nulos, se não está entre os ids anteriores - return None - else: - raise ForeignKeyFaltando(field=field, valor=valor, old=old) - - -def exec_sql(sql, db='default'): - cursor = connections[db].cursor() - cursor.execute(sql) - return cursor - - -exec_legado = partial(exec_sql, db='legacy') - - -def _formatar_lista_para_sql(iteravel): - lista = list(iteravel) - if lista: - return '({})'.format(str(lista)[1:-1]) # transforma "[...]" em "(...)" - else: - return None - - -def exec_legado_em_subconjunto(sql, ids): - """Executa uma query sql no legado no formato '.... in {}' - interpolando `ids`, se houver ids""" - - lista_sql = _formatar_lista_para_sql(ids) - if lista_sql: - return exec_legado(sql.format(lista_sql)) - else: - return [] - - -def primeira_coluna(cursor): - return (r[0] for r in cursor) - - -# UNIFORMIZAÇÃO DO BANCO ANTES DA MIGRAÇÃO ############################### - -SQL_NAO_TEM_TABELA = ''' - SELECT count(*) - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME="{}" -''' - - -def existe_tabela_no_legado(tabela): - sql = SQL_NAO_TEM_TABELA.format(tabela) - return list(primeira_coluna(exec_legado(sql)))[0] - - -def existe_coluna_no_legado(tabela, coluna): - sql_nao_tem_coluna = SQL_NAO_TEM_TABELA + ' AND COLUMN_NAME="{}"' - sql = sql_nao_tem_coluna.format(tabela, coluna) - return list(primeira_coluna(exec_legado(sql)))[0] > 0 - - -def garante_coluna_no_legado(tabela, spec_coluna): - coluna = spec_coluna.split()[0] - if not existe_coluna_no_legado(tabela, coluna): - exec_legado('ALTER TABLE {} ADD COLUMN {}'.format(tabela, spec_coluna)) - assert existe_coluna_no_legado(tabela, coluna) - - -def garante_tabela_no_legado(create_table): - tabela = create_table.strip().splitlines()[0].split()[2] - if not existe_tabela_no_legado(tabela): - exec_legado(create_table) - assert existe_tabela_no_legado(tabela) - - -TABELAS_REFERENCIANDO_AUTOR = [ - # , - ('autoria', True), - ('documento_administrativo', True), - ('proposicao', True), - ('protocolo', False)] - - -def reverte_exclusao_de_autores_referenciados_no_legado(): - """Reverte a exclusão de autores que sejam referenciados de alguma forma - na base legada""" - - def get_autores_referenciados(tabela, tem_ind_excluido): - sql = '''select distinct cod_autor from {} - where cod_autor is not null - '''.format(tabela) - if tem_ind_excluido: - sql += ' and ind_excluido != 1' - return primeira_coluna(exec_legado(sql)) - - # reverte exclusões de autores referenciados por outras tabelas - autores_referenciados = { - cod - for tabela, tem_ind_excluido in TABELAS_REFERENCIANDO_AUTOR - for cod in get_autores_referenciados(tabela, tem_ind_excluido)} - exec_legado_em_subconjunto( - 'update autor set ind_excluido = 0 where cod_autor in {}', - autores_referenciados) - - # propaga exclusões para autores não referenciados - for tabela, fk in [('parlamentar', 'cod_parlamentar'), - ('comissao', 'cod_comissao')]: - sql = ''' - update autor set ind_excluido = 1 - where {cod_parlamentar} is not null - and {cod_parlamentar} not in ( - select {cod_parlamentar} from {parlamentar} - where ind_excluido <> 1) - '''.format(parlamentar=tabela, cod_parlamentar=fk) - if autores_referenciados: - sql += ' and cod_autor not in ({})'.format( - ', '.join(map(str, autores_referenciados))) - exec_legado(sql) - - -def get_reapontamento_de_autores_repetidos(autores): - """ Dada uma lista ordenada de pares (cod_zzz, cod_autor) retorna: - - * a lista de grupos de cod_autor'es repetidos - (quando há mais de um cod_autor para um mesmo cod_zzz) - - * a lista de cod_autor'es a serem apagados (todos além do 1o de cada grupo) - """ - grupos_de_repetidos = [ - [cod_autor for _, cod_autor in grupo] - for cod_zzz, grupo in groupby(autores, lambda r: r[0])] - # mantém apenas os grupos com mais de um autor por cod_zzz - grupos_de_repetidos = [g for g in grupos_de_repetidos if len(g) > 1] - # aponta cada autor de cada grupo de repetidos para o 1o do seu grupo - reapontamento = {autor: grupo[0] - for grupo in grupos_de_repetidos - for autor in grupo} - # apagaremos todos menos o primeiro - apagar = [k for k, v in reapontamento.items() if k != v] - return reapontamento, apagar - - -def get_autorias_sem_repeticoes(autoria, reapontamento): - "Autorias sem repetições de autores e com ind_primeiro_autor ajustado" - - # substitui cada autor repetido pelo 1o de seu grupo - autoria = sorted((reapontamento[a], m, i) for a, m, i in autoria) - # agrupa por [autor (1o do grupo de repetidos), materia], com - # ind_primeiro_autor == 1 se isso acontece em qualquer autor do grupo - autoria = [(a, m, max(i for a, m, i in grupo)) - for (a, m), grupo in groupby(autoria, lambda x: x[:2])] - return autoria - - -def unifica_autores_repetidos_no_legado(campo_agregador): - "Reúne autores repetidos em um único, antes da migracão" - - # enumeramos a repeticoes segundo o campo relevante - # (p. ex. cod_parlamentar ou cod_comissao) - # a ordenação prioriza, as entradas: - # - não excluidas, - # - em seguida as que têm col_username, - # - em seguida as que têm des_cargo - autores = exec_legado(''' - select {cod_parlamentar}, cod_autor from autor - where {cod_parlamentar} is not null - order by {cod_parlamentar}, - ind_excluido, col_username desc, des_cargo desc'''.format( - cod_parlamentar=campo_agregador)) - - reapontamento, apagar = get_reapontamento_de_autores_repetidos(autores) - - # se não houver autores repetidos encerramos por aqui - if not reapontamento: - return - - # Reaponta AUTORIA (many-to-many) - - # simplificamos retirando inicialmente as autorias excluidas - exec_legado('delete from autoria where ind_excluido = 1') - - # selecionamos as autorias envolvidas em repetições de autores - from_autoria = ' from autoria where cod_autor in {}' - autoria = exec_legado_em_subconjunto( - 'select cod_autor, cod_materia, ind_primeiro_autor' + from_autoria, - reapontamento) - - # apagamos todas as autorias envolvidas - exec_legado_em_subconjunto('delete ' + from_autoria, reapontamento) - # e depois inserimos apenas as sem repetições c ind_primeiro_autor ajustado - nova_autoria = get_autorias_sem_repeticoes(autoria, reapontamento) - if nova_autoria: - exec_legado(''' - insert into autoria - (cod_autor, cod_materia, ind_primeiro_autor, ind_excluido) - values {}'''.format(', '.join([str((a, m, i, 0)) - for a, m, i in nova_autoria]))) - - # Reaponta outras tabelas que referenciam autor - for tabela, _ in TABELAS_REFERENCIANDO_AUTOR: - for antigo, novo in reapontamento.items(): - if antigo != novo: - exec_legado(''' - update {} set cod_autor = {} where cod_autor = {} - '''.format(tabela, novo, antigo)) - - # Finalmente excluimos os autores redundantes, - # cujas referências foram todas substituídas a essa altura - exec_legado_em_subconjunto('delete from autor where cod_autor in {}', - apagar) - - -def anula_tipos_origem_externa_invalidos(): - """Anula tipos de origem externa inválidos - para que não impeçam a migração da matéria""" - - tipos_validos = primeira_coluna(exec_legado(''' - select tip_materia - from tipo_materia_legislativa - where ind_excluido <> 1;''')) - - exec_legado_em_subconjunto(''' - update materia_legislativa - set tip_origem_externa = NULL - where tip_origem_externa not in {};''', tipos_validos) - - -def get_ids_registros_votacao_para(tabela): - sql = ''' - select r.cod_votacao from {} o - inner join registro_votacao r on - o.cod_ordem = r.cod_ordem and o.cod_materia = r.cod_materia - where o.ind_excluido != 1 and r.ind_excluido != 1 - order by o.cod_sessao_plen, num_ordem - '''.format(tabela) - return set(primeira_coluna(exec_legado(sql))) - - -def checa_registros_votacao_ambiguos_e_remove_nao_usados(): - """Interrompe a migração caso restem registros de votação - que apontam para uma ordem_dia e um expediente_materia ao mesmo tempo. - - Remove do legado registros de votação que não têm - nem ordem_dia nem expediente_materia associados.""" - - ordem, expediente = [ - get_ids_registros_votacao_para(tabela) - for tabela in ('ordem_dia', 'expediente_materia')] - - # interrompe migração se houver registros ambíguos - ambiguos = ordem.intersection(expediente) - como_resolver = get_como_resolver_registro_votacao_ambiguo() - ambiguos = ambiguos - set(como_resolver) - - if ambiguos: - warn('registro_votacao_ambiguos', - 'Existe(m) RegistroVotacao ambíguo(s): {cod_votacao}', - {'cod_votacao': ambiguos}) - - # exclui registros não usados (zumbis) - todos = set(primeira_coluna(exec_legado( - 'select cod_votacao from registro_votacao'))) - nao_usados = todos - ordem.union(expediente) - exec_legado_em_subconjunto(''' - update registro_votacao set ind_excluido = 1 - where cod_votacao in {}''', nao_usados) - - -PROPAGACOES_DE_EXCLUSAO = [ - # sessao_legislativa - ('sessao_legislativa', 'composicao_mesa', 'cod_sessao_leg'), - - # parlamentar - ('parlamentar', 'dependente', 'cod_parlamentar'), - ('parlamentar', 'filiacao', 'cod_parlamentar'), - ('parlamentar', 'mandato', 'cod_parlamentar'), - ('parlamentar', 'composicao_mesa', 'cod_parlamentar'), - ('parlamentar', 'composicao_comissao', 'cod_parlamentar'), - # no 2.5 os parlamentares excluídos não são listados na presença da sessão - ('parlamentar', 'sessao_plenaria_presenca', 'cod_parlamentar'), - # ... nem na presença da ordem do dia - ('parlamentar', 'ordem_dia_presenca', 'cod_parlamentar'), - # ... nem na mesa da sessão - ('parlamentar', 'mesa_sessao_plenaria', 'cod_parlamentar'), - - # coligacao - ('coligacao', 'composicao_coligacao', 'cod_coligacao'), - - # comissao - ('comissao', 'composicao_comissao', 'cod_comissao'), - ('periodo_comp_comissao', 'composicao_comissao', 'cod_periodo_comp'), - - # sessao - ('sessao_plenaria', 'ordem_dia', 'cod_sessao_plen'), - ('sessao_plenaria', 'expediente_materia', 'cod_sessao_plen'), - ('sessao_plenaria', 'expediente_sessao_plenaria', 'cod_sessao_plen'), - ('sessao_plenaria', 'sessao_plenaria_presenca', 'cod_sessao_plen'), - ('sessao_plenaria', 'ordem_dia_presenca', 'cod_sessao_plen'), - ('sessao_plenaria', 'mesa_sessao_plenaria', 'cod_sessao_plen'), - ('sessao_plenaria', 'oradores', 'cod_sessao_plen'), - ('sessao_plenaria', 'oradores_expediente', 'cod_sessao_plen'), - - # as consultas no código do sapl 2.5 - # votacao_ordem_dia_obter_zsql e votacao_expediente_materia_obter_zsql - # indicam que os registros de votação de matérias excluídas não são - # exibidos... - ('materia_legislativa', 'registro_votacao', 'cod_materia'), - # as exclusões de registro_votacao sem referência - # nem a ordem_dia nem a expediente_materia são feitas num método à parte - - # materia - ('materia_legislativa', 'tramitacao', 'cod_materia'), - ('materia_legislativa', 'autoria', 'cod_materia'), - ('materia_legislativa', 'anexada', 'cod_materia_principal'), - ('materia_legislativa', 'anexada', 'cod_materia_anexada'), - ('materia_legislativa', 'documento_acessorio', 'cod_materia'), - ('materia_legislativa', 'numeracao', 'cod_materia'), - ('materia_legislativa', 'expediente_materia', 'cod_materia'), - ('materia_legislativa', 'ordem_dia', 'cod_materia'), - ('materia_legislativa', 'acomp_materia', 'cod_materia'), - ('materia_legislativa', 'despacho_inicial', 'cod_materia'), - ('materia_legislativa', 'legislacao_citada', 'cod_materia'), - ('materia_legislativa', 'relatoria', 'cod_materia'), - ('materia_legislativa', 'materia_assunto', 'cod_materia'), - - - # norma - ('norma_juridica', 'vinculo_norma_juridica', 'cod_norma_referente'), - ('norma_juridica', 'vinculo_norma_juridica', 'cod_norma_referida'), - ('norma_juridica', 'legislacao_citada', 'cod_norma'), - - # documento administrativo - ('documento_administrativo', 'tramitacao_administrativo', 'cod_documento'), -] - -PROPAGACOES_DE_EXCLUSAO_REGISTROS_VOTACAO = [ - ('registro_votacao', 'registro_votacao_parlamentar', 'cod_votacao'), -] - - -def propaga_exclusoes(propagacoes): - for tabela_pai, tabela_filha, fk in propagacoes: - [pk_pai] = get_pk_legado(tabela_pai) - sql = ''' - update {} set ind_excluido = 1 where {} not in ( - select {} from {} where ind_excluido != 1) - '''.format(tabela_filha, fk, pk_pai, tabela_pai) - exec_legado(sql) - - -def corrige_unidades_tramitacao_destino_vazia_como_anterior(): - """Se uma unidade de tramitação estiver vazia no legado a configura - como a anterior""" - - for tabela_tramitacao in ['tramitacao', 'tramitacao_administrativo']: - exec_legado(''' - update {} - set cod_unid_tram_dest = cod_unid_tram_local - where cod_unid_tram_dest is null; - '''.format(tabela_tramitacao)) - - -def apaga_ref_a_mats_e_docs_inexistentes_em_proposicoes(): - # as referencias a matérias e documentos apagados não aparecem no 3.1 - # além do que, se ressuscitássemos essas matérias e docs, - # não seria possível apagá-los, - # pois é impossível para um usuário não autor acessar as proposicões - # para apagar a referências antes - exec_legado(''' - update proposicao set cod_materia = NULL where cod_materia not in ( - select cod_materia from materia_legislativa - where ind_excluido <> 1); - ''') - props_sem_mats = list(primeira_coluna(exec_legado(''' - select cod_proposicao from proposicao p inner join tipo_proposicao t - on p.tip_proposicao = t.tip_proposicao - where t.ind_mat_ou_doc = 'M' and cod_mat_ou_doc not in ( - select cod_materia from materia_legislativa - where ind_excluido <> 1) - '''))) - props_sem_docs = list(primeira_coluna(exec_legado(''' - select cod_proposicao from proposicao p inner join tipo_proposicao t - on p.tip_proposicao = t.tip_proposicao - where t.ind_mat_ou_doc = 'D' and cod_mat_ou_doc not in ( - select cod_documento from documento_acessorio - where ind_excluido <> 1); - '''))) - exec_legado_em_subconjunto(''' - update proposicao set cod_mat_ou_doc = NULL - where cod_proposicao in {}''', props_sem_mats + props_sem_docs) - - -def uniformiza_banco(): - propaga_exclusoes(PROPAGACOES_DE_EXCLUSAO) - checa_registros_votacao_ambiguos_e_remove_nao_usados() - propaga_exclusoes(PROPAGACOES_DE_EXCLUSAO_REGISTROS_VOTACAO) - - garante_coluna_no_legado('proposicao', - 'num_proposicao int(11) NULL') - - garante_coluna_no_legado('tipo_materia_legislativa', - 'ind_num_automatica BOOLEAN NULL DEFAULT FALSE') - - garante_coluna_no_legado('tipo_materia_legislativa', - 'quorum_minimo_votacao int(11) NULL') - - garante_coluna_no_legado('materia_legislativa', - 'txt_resultado TEXT NULL') - - # Cria campos cod_presenca_sessao (sendo a nova PK da tabela) - # e dat_sessao em sessao_plenaria_presenca - if not existe_coluna_no_legado('sessao_plenaria_presenca', - 'cod_presenca_sessao'): - exec_legado(''' - ALTER TABLE sessao_plenaria_presenca - DROP PRIMARY KEY, - ADD cod_presenca_sessao INT auto_increment PRIMARY KEY FIRST; - ''') - assert existe_coluna_no_legado('sessao_plenaria_presenca', - 'cod_presenca_sessao') - - garante_coluna_no_legado('sessao_plenaria_presenca', - 'dat_sessao DATE NULL') - - garante_tabela_no_legado(''' - 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)); - ''') - - garante_tabela_no_legado(''' - 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)); - ''') - - garante_tabela_no_legado(''' - CREATE TABLE tipo_situacao_militar ( - tip_situacao_militar INT auto_increment NOT NULL, - des_tipo_situacao varchar(50), - ind_excluido INT, PRIMARY KEY (tip_situacao_militar)); - ''') - - update_specs = ''' -vinculo_norma_juridica | ind_excluido = '' | trim(ind_excluido) = '0' -unidade_tramitacao | cod_parlamentar = NULL | cod_parlamentar = 0 -parlamentar | cod_nivel_instrucao = NULL | cod_nivel_instrucao = 0 -parlamentar | tip_situacao_militar = NULL | tip_situacao_militar = 0 -mandato | tip_afastamento = NULL | tip_afastamento = 0 -relatoria | tip_fim_relatoria = NULL | tip_fim_relatoria = 0 -sessao_plenaria_presenca | dat_sessao = NULL | dat_sessao = 0 - '''.strip().splitlines() - - for spec in update_specs: - spec = spec.split('|') - exec_legado('UPDATE {} SET {} WHERE {}'.format(*spec)) - - # retira apontamentos de materia para assunto inexistente - exec_legado('delete from materia_assunto where cod_assunto = 0') - - # corrige string "None" em autor - exec_legado('update autor set des_cargo = NULL where des_cargo = "None"') - - unifica_autores_repetidos_no_legado('cod_parlamentar') - unifica_autores_repetidos_no_legado('cod_comissao') - unifica_autores_repetidos_no_legado('col_username') - - # é importante reverter a exclusão de autores somente depois, para que a - # unificação possa dar prioridade às informações dos autores não excluídos - reverte_exclusao_de_autores_referenciados_no_legado() - - anula_tipos_origem_externa_invalidos() - corrige_unidades_tramitacao_destino_vazia_como_anterior() - - # matérias inexistentes não são mostradas em norma jurídica => apagamos - exec_legado('''update norma_juridica set cod_materia = NULL - where cod_materia not in ( - select cod_materia from materia_legislativa - where ind_excluido <> 1);''') - - apaga_ref_a_mats_e_docs_inexistentes_em_proposicoes() - - -class Record: - pass - - -def iter_sql_records(tabela): - if tabela == 'despacho_inicial': - sql = ''' select cod_materia, cod_comissao from despacho_inicial - where ind_excluido <> 1 - group by cod_materia, cod_comissao - order by cod_materia, min(num_ordem) - ''' - else: - sql = 'select * from ' + tabela - if existe_coluna_no_legado(tabela, 'ind_excluido'): - sql += ' where ind_excluido <> 1' - cursor = exec_legado(sql) - fieldnames = [name[0] for name in cursor.description] - for row in cursor.fetchall(): - record = Record() - record.__dict__.update(zip(fieldnames, row)) - yield record - - -def fill_vinculo_norma_juridica(): - 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) - - -def fill_dados_basicos(): - # Ajusta sequencia numérica de protocolo e cria base.AppConfig - if (TipoNumeracaoProtocolo._meta.db_table in TABELAS_LEGADO - and TipoNumeracaoProtocolo.objects.exists()): - # se este banco legado tem a a configuração de numeração de protocolo - tipo = TipoNumeracaoProtocolo.objects.latest('dat_inicial_protocolo') - descricao = tipo.des_numeracao_protocolo - if 'POR ANO' in descricao: - sequencia_numeracao = 'A' - elif 'POR LEGISLATURA' in descricao: - sequencia_numeracao = 'L' - elif 'CONSECUTIVO' in descricao: - sequencia_numeracao = 'U' - else: - sequencia_numeracao = 'A' - appconf = AppConf(sequencia_numeracao=sequencia_numeracao) - appconf.save() - - -def reinicia_sequence(model, id): - sequence_name = '%s_id_seq' % model._meta.db_table - exec_sql('ALTER SEQUENCE %s RESTART WITH %s MINVALUE -1;' % ( - sequence_name, id)) - - -REPO = git.Repo.init(DIR_REPO) - - -def populate_renamed_fields(new, old): - renames = field_renames[type(new)] - - for field in new._meta.fields: - old_field_name = renames.get(field.name) - if old_field_name: - field_type = field.get_internal_type() - - if field_type == 'ForeignKey': - fk_field_name = '{}_id'.format(field.name) - value = get_fk_related(field, old) - setattr(new, fk_field_name, value) - else: - value = getattr(old, old_field_name) - - if (field_type in ['CharField', 'TextField'] - and value in [None, 'None']): - value = '' - - # ajusta tempos segundo timezone - # os campos TIMESTAMP do mysql são gravados em UTC - # os DATETIME e TIME não têm timezone - - if field_type == 'DateTimeField' and value: - # as datas armazenadas no legado na verdade são naive - sem_tz = value.replace(tzinfo=None) - value = PYTZ_TIMEZONE.localize(sem_tz).astimezone(pytz.utc) - - if field_type == 'TimeField' and value: - value = value.replace(tzinfo=PYTZ_TIMEZONE) - - setattr(new, field.name, value) - - -def roda_comando_shell(cmd): - res = os.system(cmd) - assert res == 0, 'O comando falhou: {}'.format(cmd) - - -def get_arquivo_ajustes_pre_migracao(): - return DIR_DADOS_MIGRACAO.child( - 'ajustes_pre_migracao', '{}.sql'.format(SIGLA_CASA)) - - -def migrar_dados(apagar_do_legado=False): - try: - ocorrencias.clear() - ocorrencias.default_factory = list - - # restaura dump - arq_dump = Path(DIR_DADOS_MIGRACAO.child( - 'dumps_mysql', '{}.sql'.format(NOME_BANCO_LEGADO))) - assert arq_dump.exists(), 'Dump do mysql faltando: {}'.format(arq_dump) - info('Restaurando dump mysql de [{}]'.format(arq_dump)) - normaliza_dump_mysql(arq_dump) - roda_comando_shell('mysql -uroot < {}'.format(arq_dump)) - - # desliga checagens do mysql - # e possibilita inserir valor zero em campos de autoincremento - exec_legado('SET SESSION sql_mode = "NO_AUTO_VALUE_ON_ZERO";') - - # executa ajustes pré-migração, se existirem - arq_ajustes_pre_migracao = get_arquivo_ajustes_pre_migracao() - if arq_ajustes_pre_migracao.exists(): - exec_legado(arq_ajustes_pre_migracao.read_file()) - - uniformiza_banco() - - # excluindo database antigo. - info('Excluindo entradas antigas do banco destino.') - flush = FlushCommand() - flush.handle(database='default', interactive=False, verbosity=0) - - # apaga tipos de autor padrão (criados no flush acima) - TipoAutor.objects.all().delete() - - fill_vinculo_norma_juridica() - fill_dados_basicos() - info('Começando migração: ...') - migrar_todos_os_models(apagar_do_legado) - except Exception as e: - ocorrencias['traceback'] = str(traceback.format_exc()) - raise e - finally: - # congela e grava ocorrências - ocorrencias.default_factory = None - arq_ocorrencias = Path(REPO.working_dir, 'ocorrencias.yaml') - with open(arq_ocorrencias, 'w') as arq: - pyaml.dump(ocorrencias, arq, vspacing=1, width=200) - REPO.git.add([arq_ocorrencias.name]) - info('Ocorrências salvas em\n {}'.format(arq_ocorrencias)) - if not ocorrencias: - info('NÃO HOUVE OCORRÊNCIAS !!!') - - # recria tipos de autor padrão que não foram criados pela migração - cria_models_tipo_autor() - - -def move_para_depois_de(lista, movido, referencias): - indice_inicial = lista.index(movido) - lista.remove(movido) - indice_apos_refs = max(lista.index(r) for r in referencias) + 1 - lista.insert(max(indice_inicial, indice_apos_refs), movido) - return lista - - -TABELAS_LEGADO = [t for (t,) in exec_legado('show tables')] -EXISTE_REUNIAO_NO_LEGADO = 'reuniao_comissao' in TABELAS_LEGADO - - -def get_models_a_migrar(): - models = [model for app in appconfs for model in app.models.values() - if model in field_renames] - # retira reuniões quando não existe na base legada - # (só existe no sapl 3.0) - if not EXISTE_REUNIAO_NO_LEGADO: - models.remove(Reuniao) - # Devido à referência TipoProposicao.tipo_conteudo_related - # a migração de TipoProposicao precisa ser feita - # após TipoMateriaLegislativa e TipoDocumento - # (porém antes de Proposicao) - move_para_depois_de(models, TipoProposicao, - [TipoMateriaLegislativa, TipoDocumento]) - assert models.index(TipoProposicao) < models.index(Proposicao) - move_para_depois_de(models, Proposicao, - [MateriaLegislativa, DocumentoAcessorio]) - - return models - - -def migrar_todos_os_models(apagar_do_legado): - for model in get_models_a_migrar(): - migrar_model(model, apagar_do_legado) - - -def migrar_model(model, apagar_do_legado): - print('Migrando %s...' % model.__name__) - - model_legado, tabela_legado, campos_pk_legado = \ - get_estrutura_legado(model) - - if len(campos_pk_legado) == 1: - # a pk no legado tem um único campo - nome_pk = model_legado._meta.pk.name - if 'ind_excluido' in {f.name for f in model_legado._meta.fields}: - # se o model legado tem o campo ind_excluido - # enumera apenas os não excluídos - old_records = model_legado.objects.filter(~Q(ind_excluido=1)) - else: - old_records = model_legado.objects.all() - old_records = old_records.order_by(nome_pk) - - def get_id_do_legado(old): - return getattr(old, nome_pk) - - ultima_pk_legado = model_legado.objects.all().aggregate( - Max('pk'))['pk__max'] or 0 - else: - # a pk no legado tem mais de um campo - old_records = iter_sql_records(tabela_legado) - get_id_do_legado = None - ultima_pk_legado = model_legado.objects.count() - - ajuste_antes_salvar = AJUSTE_ANTES_SALVAR.get(model) - ajuste_depois_salvar = AJUSTE_DEPOIS_SALVAR.get(model) - - # convert old records to new ones - with transaction.atomic(): - novos = [] - sql_delete_legado = '' - for old in old_records: - new = model() - if get_id_do_legado: - new.id = get_id_do_legado(old) - try: - populate_renamed_fields(new, old) - if ajuste_antes_salvar: - ajuste_antes_salvar(new, old) - except ForeignKeyFaltando as e: - # tentamos preencher uma FK e o ojeto relacionado - # não existe - # então este é um objeo órfão: simplesmente ignoramos - warn('fk', e.msg, e.dados) - continue - else: - new.clean() # valida model - novos.append(new) # guarda para salvar - - # acumula deleção do registro no legado - if apagar_do_legado: - sql_delete_legado += 'delete from {} where {};\n'.format( - tabela_legado, - ' and '.join( - '{} = "{}"'.format(campo, - getattr(old, campo)) - for campo in campos_pk_legado)) - - # salva novos registros - with reversion.create_revision(): - model.objects.bulk_create(novos) - reversion.set_comment('Objetos criados pela migração') - - if ajuste_depois_salvar: - ajuste_depois_salvar() - - # reiniciamos a sequence logo após a última pk do legado - # - # É importante que seja do legado (e não da nova base), - # pois numa nova versão da migração podemos inserir registros - # não migrados antes sem conflito com pks criadas até lá - if get_id_do_legado: - reinicia_sequence(model, ultima_pk_legado + 1) - - # apaga registros migrados do legado - if apagar_do_legado and sql_delete_legado: - exec_legado(sql_delete_legado) - - -# MIGRATION_ADJUSTMENTS ##################################################### - -def adjust_acompanhamentomateria(new, old): - new.confirmado = True - - -def adjust_documentoadministrativo(new, old): - if old.num_protocolo: - numero, ano = old.num_protocolo, new.ano - # False < True => o primeiro será o protocolo não anulado - protocolos = Protocolo.objects.filter( - numero=numero, ano=ano).order_by('anulado') - if protocolos: - new.protocolo = protocolos[0] - else: - # Se não achamos o protocolo registramos no número externo - new.numero_externo = numero - - nota = ''' -## NOTA DE MIGRAÇÃO DE DADOS DO SAPL 2.5 ## -O número de protocolo original deste documento era [{numero}], ano [{ano}]. - -Não existe no sistema nenhum protocolo com estes dados -e portanto nenhum protocolo foi vinculado a este documento. - -Colocamos então o número de protocolo no campo "número externo". -''' - nota = nota.strip().format(numero=numero, ano=ano) - msg = 'Protocolo {numero} faltando (referenciado ' \ - 'no documento administrativo {cod_documento})' - warn('protocolo_faltando', msg, - {'numero': numero, - 'cod_documento': old.cod_documento, - 'nota': nota}) - new.observacao += ('\n\n' if new.observacao else '') + nota - - -def adjust_mandato(new, old): - if old.dat_fim_mandato: - new.data_fim_mandato = old.dat_fim_mandato - if not new.data_fim_mandato: - legislatura = Legislatura.objects.latest('data_fim') - new.data_fim_mandato = legislatura.data_fim - new.data_expedicao_diploma = legislatura.data_inicio - if not new.data_inicio_mandato: - new.data_inicio_mandato = new.legislatura.data_inicio - new.data_fim_mandato = new.legislatura.data_fim - - -def adjust_ordemdia_antes_salvar(new, old): - new.votacao_aberta = False - - if not old.tip_votacao: - new.tipo_votacao = 1 - - if old.num_ordem is None: - new.numero_ordem = 999999999 - warn('ordem_dia_num_ordem_nulo', - 'OrdemDia de PK {pk} tinha numero ordem nulo. ' - 'O valor %s foi colocado no lugar.' % new.numero_ordem, - {'pk': old.pk}) - - -def adjust_parlamentar(new, old): - if old.ind_unid_deliberativa: - value = new.unidade_deliberativa - # Field is defined as not null in legacy db, - # but data includes null values - # => transform None to False - if value is None: - warn('unidade_deliberativa_nulo_p_false', - 'nulo convertido para falso na unidade_deliberativa ' - 'do parlamentar {pk_parlamentar}', - {'pk_parlamentar': old.cod_parlamentar}) - new.unidade_deliberativa = False - # migra município de residência - if old.cod_localidade_resid: - municipio_uf = list(exec_legado(''' - select nom_localidade, sgl_uf from localidade - where cod_localidade = {}'''.format(old.cod_localidade_resid))) - if municipio_uf: - new.municipio_residencia, new.uf_residencia = municipio_uf[0] - - -def adjust_participacao(new, old): - comissao_id, periodo_id = [ - get_fk_related(Composicao._meta.get_field(name), old) - for name in ('comissao', 'periodo')] - with reversion.create_revision(): - composicao, _ = Composicao.objects.get_or_create( - comissao_id=comissao_id, periodo_id=periodo_id) - reversion.set_comment('Objeto criado pela migração') - new.composicao = composicao - - -def adjust_normarelacionada(new, old): - new.tipo_vinculo = TipoVinculoNormaJuridica.objects.get( - sigla=old.tip_vinculo) - - -def adjust_protocolo_antes_salvar(new, old): - if new.numero is None: - new.numero = old.cod_protocolo - warn('num_protocolo_nulo', - 'Número do protocolo de PK {cod_protocolo} era nulo ' - 'e foi alterado para sua pk ({cod_protocolo})', - {'cod_protocolo': old.cod_protocolo}) - - -def get_arquivo_resolve_registro_votacao(): - return DIR_DADOS_MIGRACAO.child( - 'ajustes_pre_migracao', - '{}_resolve_registro_votacao_ambiguo.yaml'.format(SIGLA_CASA)) - - -def get_como_resolver_registro_votacao_ambiguo(): - path = get_arquivo_resolve_registro_votacao() - if path.exists(): - return yaml.load(path.read_file(), yaml.Loader) - else: - return {} - - -def adjust_registrovotacao_antes_salvar(new, old): - ordem_dia = OrdemDia.objects.filter( - pk=old.cod_ordem, materia=old.cod_materia) - expediente_materia = ExpedienteMateria.objects.filter( - pk=old.cod_ordem, materia=old.cod_materia) - - if ordem_dia and not expediente_materia: - new.ordem = ordem_dia[0] - if not ordem_dia and expediente_materia: - new.expediente = expediente_materia[0] - # registro de votação ambíguo - if ordem_dia and expediente_materia: - como_resolver = get_como_resolver_registro_votacao_ambiguo() - campo = como_resolver[new.id] - if campo.startswith('ordem'): - new.ordem = ordem_dia[0] - elif campo.startswith('expediente'): - new.expediente = expediente_materia[0] - else: - raise Exception(''' - Registro de Votação ambíguo: {} - Resolva criando o arquivo {}'''.format( - new.id, get_arquivo_resolve_registro_votacao())) - - -def adjust_tipoafastamento(new, old): - assert xor(old.ind_afastamento, old.ind_fim_mandato) - if old.ind_afastamento: - new.indicador = 'A' - elif old.ind_fim_mandato: - new.indicador = 'F' - - -def set_generic_fk(new, campo_virtual, old): - model = campo_virtual.related_model - new.content_type = ContentType.objects.get( - app_label=model._meta.app_label, model=model._meta.model_name) - new.object_id = get_fk_related(campo_virtual, old) - - -def adjust_tipoproposicao(new, old): - "Aponta para o tipo relacionado de matéria ou documento" - if old.tip_mat_ou_doc is not None: - campo_virtual = CAMPOS_VIRTUAIS_TIPO_PROPOSICAO[old.ind_mat_ou_doc] - set_generic_fk(new, campo_virtual, old) - - -def adjust_proposicao_antes_salvar(new, old): - if new.data_envio: - new.ano = new.data_envio.year - if old.cod_mat_ou_doc is not None: - tipo_mat_ou_doc = type(new.tipo.tipo_conteudo_related) - campo_virtual = CAMPOS_VIRTUAIS_PROPOSICAO[tipo_mat_ou_doc] - set_generic_fk(new, campo_virtual, old) - - -def adjust_statustramitacao(new, old): - if old.ind_fim_tramitacao: - new.indicador = 'F' - elif old.ind_retorno_tramitacao: - new.indicador = 'R' - else: - new.indicador = '' - - -def adjust_statustramitacaoadm(new, old): - adjust_statustramitacao(new, old) - - -def adjust_tramitacao(new, old): - if old.sgl_turno == 'Ú': - new.turno = 'U' - - -def adjust_tipo_autor(new, old): - model_apontado = normalize(new.descricao.lower()).replace(' ', '') - content_types = ContentType.objects.filter( - model=model_apontado).exclude(app_label='legacy') - assert len(content_types) <= 1 - new.content_type = content_types[0] if content_types else None - - -def adjust_normajuridica_antes_salvar(new, old): - # Ajusta choice de esfera_federacao - # O 'S' vem de 'Selecionar'. Na versão antiga do SAPL, quando uma opção do - # combobox era selecionada, o sistema pegava a primeira letra da seleção, - # sendo F para Federal, E para Estadual, M para Municipal e o S para - # Selecionar, que era a primeira opção quando nada era selecionado. - if old.tip_esfera_federacao == 'S': - new.esfera_federacao = '' - - -def adjust_normajuridica_depois_salvar(): - # Ajusta relação M2M - ligacao = NormaJuridica.assuntos.through - - assuntos_migrados, normas_migradas = [ - set(model.objects.values_list('id', flat=True)) - for model in [AssuntoNorma, NormaJuridica]] - - def filtra_assuntos_migrados(cod_assunto): - if not cod_assunto: - return [] - cods = {int(a) for a in cod_assunto.split(',') if a} - return sorted(cods.intersection(assuntos_migrados)) - - norma_para_assuntos = [ - (norma, filtra_assuntos_migrados(cod_assunto)) - for norma, cod_assunto in OldNormaJuridica.objects.filter( - pk__in=normas_migradas).values_list('pk', 'cod_assunto')] - - ligacao.objects.bulk_create( - ligacao(normajuridica_id=norma, assuntonorma_id=assunto) - for norma, assuntos in norma_para_assuntos - for assunto in assuntos) - - -def adjust_autor(new, old): - # vincula autor com o objeto relacionado, tentando os três campos antigos - # o primeiro campo preenchido será usado, podendo lançar ForeignKeyFaltando - for model_relacionado, campo_nome in [(Parlamentar, 'nome_parlamentar'), - (Comissao, 'nome'), - (Partido, 'nome')]: - field = CAMPOS_VIRTUAIS_AUTOR[model_relacionado] - fk_encontrada = get_fk_related(field, old) - if fk_encontrada: - new.autor_related = model_relacionado.objects.get(id=fk_encontrada) - new.nome = getattr(new.autor_related, campo_nome) - break - - if old.col_username: - user, created = get_user_model().objects.get_or_create( - username=old.col_username) - if created: - # gera uma senha inutilizável, que precisará ser trocada - user.set_password(None) - with reversion.create_revision(): - user.save() - reversion.set_comment( - 'Usuário criado pela migração para o autor {}'.format( - old.cod_autor)) - grupo_autor = Group.objects.get(name="Autor") - user.groups.add(grupo_autor) - new.user = user - - -def adjust_comissao(new, old): - if not old.dat_extincao and not old.dat_fim_comissao: - new.ativa = True - elif (old.dat_extincao and date.today() < new.data_extincao or - old.dat_fim_comissao and date.today() < new.data_fim_comissao): - new.ativa = True - else: - new.ativa = False - - -def adjust_tiporesultadovotacao(new, old): - if 'aprova' in new.nome.lower(): - new.natureza = TipoResultadoVotacao.NATUREZA_CHOICES.aprovado - elif 'rejeita' in new.nome.lower(): - new.natureza = TipoResultadoVotacao.NATUREZA_CHOICES.rejeitado - elif 'retirado' in new.nome.lower(): - new.natureza = TipoResultadoVotacao.NATUREZA_CHOICES.rejeitado - else: - if new.nome != 'DESCONHECIDO': - # ignoramos a natureza de item criado pela migração - warn('natureza_desconhecida_tipo_resultadovotacao', - 'Não foi possível identificar a natureza do ' - 'tipo de resultado de votação [{pk}: "{nome}"]', - {'pk': new.pk, 'nome': new.nome}) - - -def str_to_time(fonte): - if not fonte.strip(): - return None - tempo = datetime.datetime.strptime(fonte, '%H:%M') - return tempo.time() if tempo else None - - -def adjust_reuniao_comissao(new, old): - new.hora_inicio = str_to_time(old.hr_inicio_reuniao) - - -def remove_style(conteudo): - if 'style' not in conteudo: - return conteudo # atalho que acelera muito os casos sem style - - soup = BeautifulSoup(conteudo, 'html.parser') - for tag in soup.recursiveChildGenerator(): - if hasattr(tag, 'attrs'): - tag.attrs = {k: v for k, v in tag.attrs.items() if k != 'style'} - return str(soup) - - -def adjust_expediente_sessao(new, old): - new.conteudo = remove_style(new.conteudo) - - -AJUSTE_ANTES_SALVAR = { - Autor: adjust_autor, - TipoAutor: adjust_tipo_autor, - AcompanhamentoMateria: adjust_acompanhamentomateria, - Comissao: adjust_comissao, - DocumentoAdministrativo: adjust_documentoadministrativo, - Mandato: adjust_mandato, - NormaJuridica: adjust_normajuridica_antes_salvar, - NormaRelacionada: adjust_normarelacionada, - OrdemDia: adjust_ordemdia_antes_salvar, - Parlamentar: adjust_parlamentar, - Participacao: adjust_participacao, - Proposicao: adjust_proposicao_antes_salvar, - Protocolo: adjust_protocolo_antes_salvar, - RegistroVotacao: adjust_registrovotacao_antes_salvar, - TipoAfastamento: adjust_tipoafastamento, - TipoProposicao: adjust_tipoproposicao, - StatusTramitacao: adjust_statustramitacao, - StatusTramitacaoAdministrativo: adjust_statustramitacaoadm, - Tramitacao: adjust_tramitacao, - TipoResultadoVotacao: adjust_tiporesultadovotacao, - ExpedienteSessao: adjust_expediente_sessao, - Reuniao: adjust_reuniao_comissao, -} - -AJUSTE_DEPOIS_SALVAR = { - NormaJuridica: adjust_normajuridica_depois_salvar, -} - - -# MARCO ###################################################################### - -TIME_FORMAT = '%H:%M:%S' - - -# permite a gravação de tempos puros pelo pretty-yaml -def time_representer(dumper, data): - return dumper.represent_scalar('!time', data.strftime(TIME_FORMAT)) - - -UnsafePrettyYAMLDumper.add_representer(datetime.time, time_representer) - - -# permite a leitura de tempos puros pelo pyyaml (no padrão gravado acima) -def time_constructor(loader, node): - value = loader.construct_scalar(node) - return datetime.datetime.strptime(value, TIME_FORMAT).time() - - -yaml.add_constructor(u'!time', time_constructor) - -TAG_MARCO = 'marco' - - -def gravar_marco(): - """Grava um dump de todos os dados como arquivos yaml no repo de marco - """ - # prepara ou localiza repositorio - dir_dados = Path(REPO.working_dir, 'dados') - - # exporta dados como arquivos yaml - user_model = get_user_model() - models = get_models_a_migrar() + [ - Composicao, user_model, Group, ContentType] - for model in models: - info('Gravando marco de [{}]'.format(model.__name__)) - dir_model = dir_dados.child(model._meta.app_label, model.__name__) - dir_model.mkdir(parents=True) - for data in model.objects.all().values(): - nome_arq = Path(dir_model, '{}.yaml'.format(data['id'])) - with open(nome_arq, 'w') as arq: - pyaml.dump(data, arq) - - # backup do banco - print('Gerando backup do banco... ', end='', flush=True) - arq_backup = DIR_REPO.child('{}.backup'.format(NOME_BANCO_LEGADO)) - arq_backup.remove() - backup_cmd = ''' - pg_dump --host localhost --port 5432 --username postgres --no-password - --format custom --blobs --verbose --file {} {}'''.format( - arq_backup, NOME_BANCO_LEGADO) - subprocess.check_output(backup_cmd.split(), stderr=subprocess.DEVNULL) - print('SUCESSO') - - # salva mudanças - REPO.git.add([dir_dados.name]) - REPO.git.add([arq_backup.name]) - if 'master' not in REPO.heads or REPO.index.diff('HEAD'): - # se de fato existe mudança - REPO.index.commit('Grava marco') - REPO.git.execute('git tag -f'.split() + [TAG_MARCO]) diff --git a/sapl/legacy/migracao_documentos.py b/sapl/legacy/migracao_documentos.py deleted file mode 100644 index 23c6f05f7..000000000 --- a/sapl/legacy/migracao_documentos.py +++ /dev/null @@ -1,215 +0,0 @@ -import os -import re -import shutil -from glob import glob -from os.path import join - -import yaml -from django.db import transaction -from image_cropping.fields import ImageCropField - -from sapl.base.models import CasaLegislativa -from sapl.comissoes.models import Reuniao -from sapl.legacy.migracao_dados import EXISTE_REUNIAO_NO_LEGADO, exec_legado -from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa, - Proposicao) -from sapl.norma.models import NormaJuridica -from sapl.parlamentares.models import Parlamentar -from sapl.protocoloadm.models import (DocumentoAcessorioAdministrativo, - DocumentoAdministrativo) -from sapl.sessao.models import SessaoPlenaria - -# MIGRAÇÃO DE DOCUMENTOS ################################################### - - -DOCS = { - Parlamentar: [('fotografia', 'parlamentar/fotos/{}_foto_parlamentar')], - MateriaLegislativa: [('texto_original', 'materia/{}_texto_integral')], - DocumentoAcessorio: [('arquivo', 'materia/{}')], - NormaJuridica: [('texto_integral', 'norma_juridica/{}_texto_integral')], - SessaoPlenaria: [('upload_pauta', 'pauta_sessao/{}_pauta_sessao'), - ('upload_ata', 'ata_sessao/{}_ata_sessao'), - ('upload_anexo', 'anexo_sessao/{}_texto_anexado')], - Proposicao: [('texto_original', 'proposicao/{}')], - DocumentoAdministrativo: [('texto_integral', - 'administrativo/{}_texto_integral')], - DocumentoAcessorioAdministrativo: [('arquivo', 'administrativo/{}')], -} - -# acrescenta reuniões (que só existem no sapl 3.0) -if EXISTE_REUNIAO_NO_LEGADO: - DOCS[Reuniao] = [('upload_pauta', 'reuniao_comissao/{}_pauta'), - ('upload_ata', 'reuniao_comissao/{}_ata')] - - -DOCS = {model: [(campo, join('sapl_documentos', origem)) - for campo, origem in campos] - for model, campos in DOCS.items()} - - -def mover_documento(repo, origem, destino, ignora_origem_ausente=False): - origem, destino = [join(repo.working_dir, c) if not os.path.isabs(c) else c - for c in (origem, destino)] - if ignora_origem_ausente and not os.path.exists(origem): - print('Origem ignorada ao mover documento: {}'.format(origem)) - return - # apaga destino, se houver, e renomeia origem para destino - if os.path.exists(destino): - if os.path.isdir(destino): - shutil.rmtree(destino) - else: - os.remove(destino) - os.makedirs(os.path.dirname(destino), exist_ok=True) - os.rename(origem, destino) - - -def migrar_logotipo(repo, casa, propriedades): - print('.... Migrando logotipo da casa ....') - campo, origem = 'logotipo', 'sapl_documentos/props_sapl/{}.*' - # a extensão do logo pode ter sido ajustada pelo tipo real do arquivo - nome_nas_propriedades = os.path.splitext(propriedades['id_logo'])[0] - arquivos = glob( - join(repo.working_dir, origem.format(nome_nas_propriedades))) - if arquivos: - assert len(arquivos) == 1, 'Há mais de um logotipo para a casa' - [logo] = arquivos - destino = join(CasaLegislativa._meta.get_field(campo).upload_to, - os.path.basename(logo)) - mover_documento(repo, logo, destino) - casa.logotipo = destino - - -def migrar_propriedades_da_casa(repo): - print('#### Migrando propriedades da casa ####') - caminho = join(repo.working_dir, 'sapl_documentos/propriedades.yaml') - repo.git.execute('git annex get'.split() + [caminho]) - with open(caminho, 'r') as arquivo: - propriedades = yaml.safe_load(arquivo) - casa = CasaLegislativa.objects.first() - if not casa: - casa = CasaLegislativa() - campos_para_propriedades = [('codigo', 'cod_casa'), - ('nome', 'nom_casa'), - ('sigla', 'sgl_casa'), - ('endereco', 'end_casa'), - ('cep', 'num_cep'), - ('telefone', 'num_tel'), - ('fax', 'num_fax'), - ('endereco_web', 'end_web_casa'), - ('email', 'end_email_casa'), - ('sigla', 'sgl_casa'), - ('informacao_geral', 'txt_informacao_geral')] - for campo, prop in campos_para_propriedades: - setattr(casa, campo, propriedades[prop]) - - # localidade - sql_localidade = ''' - select nom_localidade, sgl_uf from localidade - where cod_localidade = {}'''.format(propriedades['cod_localidade']) - [(casa.municipio, casa.uf)] = exec_legado(sql_localidade) - - # logotipo - migrar_logotipo(repo, casa, propriedades) - - casa.save() - - -def migrar_docs_por_ids(repo, model): - - for campo, base_origem in DOCS[model]: - print('#### Migrando {} de {} ####'.format(campo, model.__name__)) - - dir_origem, nome_origem = os.path.split( - join(repo.working_dir, base_origem)) - nome_origem = nome_origem.format('(\d+)') - pat = re.compile('^{}\.\w+$'.format(nome_origem)) - if not os.path.isdir(dir_origem): - print(' >>> O diretório {} não existe! Abortado.'.format( - dir_origem)) - continue - - matches = [pat.match(arq) for arq in os.listdir(dir_origem)] - ids_origens = [(int(m.group(1)), - join(dir_origem, m.group(0))) - for m in matches if m] - objetos = {obj.id: obj for obj in model.objects.all()} - upload_to = model._meta.get_field(campo).upload_to - tem_cropping = isinstance(model._meta.get_field(campo), ImageCropField) - - with transaction.atomic(): - for id, origem in ids_origens: - # associa documento ao objeto - obj = objetos.get(id) - if obj: - destino = upload_to(obj, os.path.basename(origem)) - mover_documento(repo, origem, destino) - setattr(obj, campo, destino) - if tem_cropping: - # conserta link do git annex (antes do commit) - # pois o conteúdo das imagens é acessado pelo cropping - repo.git.add(destino) - repo.git.execute('git annex fix'.split() + [destino]) - obj.save() - else: - msg = ' {} (pk={}) não encontrado para documento em [{}]' - print(msg.format(model.__name__, id, origem)) - - -def migrar_documentos(repo): - # aqui supomos que as pastas XSLT e sapl_documentos estão em - # com o conteúdo exportado do zope - # Os arquivos das pastas serão (git) MOVIDOS para a nova estrutura! - # - # Isto significa que para rodar novamente esta função é preciso - # restaurar o repo ao estado anterior - - mover_documento(repo, 'XSLT', 'sapl/public/XSLT', - ignora_origem_ausente=True) - - migrar_propriedades_da_casa(repo) - - # garante que o conteúdo das fotos dos parlamentares esteja presente - # (necessário para o cropping de imagem) - if os.path.exists( - os.path.join(repo.working_dir, 'sapl_documentos/parlamentar')): - repo.git.execute('git annex get sapl_documentos/parlamentar'.split()) - - for model in DOCS: - migrar_docs_por_ids(repo, model) - - # versiona modificações - repo.git.add('-A', '.') - repo.index.commit('Migração dos documentos completa') - - sobrando = [join(dir, file) - for (dir, _, files) in os.walk(join(repo.working_dir, - 'sapl_documentos')) - for file in files] - if sobrando: - print('\n#### Encerrado ####\n\n' - '{} documentos sobraram sem ser migrados!!!'.format( - len(sobrando))) - - -def corrigir_documentos_para_existentes(repo): - - for model, campos_bases in DOCS.items(): - if model == Parlamentar: - continue - for campo, base_origem in campos_bases: - print('#### Corrigindo {} de {} ####'.format(campo, - model.__name__)) - upload_to = model._meta.get_field(campo).upload_to - for obj in model.objects.all(): - if getattr(obj, campo): - continue - dir_upload_to = os.path.join( - repo.working_dir, upload_to(obj, '')) - achados = glob(dir_upload_to + '*') - if achados: - assert len(achados) == 1, 'Mais de um doc achado' - [achado] = achados - destino = upload_to(obj, os.path.basename(achado)) - print('-- {}'.format(destino)) - setattr(obj, campo, destino) - obj.save() diff --git a/sapl/legacy/migracao_usuarios.py b/sapl/legacy/migracao_usuarios.py deleted file mode 100644 index 6fa9cc7ea..000000000 --- a/sapl/legacy/migracao_usuarios.py +++ /dev/null @@ -1,109 +0,0 @@ -import yaml -from django.contrib.auth.models import Group, User -from unipath import Path - -from sapl.hashers import zope_encoded_password_to_django - -PERFIL_LEGADO_PARA_NOVO = {legado: Group.objects.get(name=novo) - for legado, novo in [ - ('Autor', 'Autor'), - ('Operador', 'Operador Geral'), - ('Operador Comissao', 'Operador de Comissões'), - ('Operador Materia', 'Operador de Matéria'), - ('Operador Modulo Administrativo', 'Operador Administrativo'), - ('Operador Norma', 'Operador de Norma Jurídica'), - ('Operador Parlamentar', 'Parlamentar'), - ('Operador Protocolo', 'Operador de Protocolo Administrativo'), - ('Operador Sessao Plenaria', 'Operador de Sessão Plenária'), - ('Parlamentar', 'Votante'), - ('Operador Painel', 'Operador de Painel Eletrônico'), -] -} - -ADMINISTRADORES = {'Administrador', 'Manager'} - -IGNORADOS = { - # sem significado fora do zope - 'Alterar Senha', 'Authenticated', 'Owner', - - # obsoletos (vide docs a seguir) - 'Operador Mesa Diretora', - 'Operador Ordem Dia', - 'Operador Tabela Auxiliar', - 'Operador Lexml', -} - - -def decode_nome(nome): - if isinstance(nome, bytes): - try: - return nome.decode('utf-8') - except UnicodeDecodeError: - return nome.decode('iso8859-1') - else: - assert isinstance(nome, str) - return nome - - -def migrar_usuarios(dir_repo): - """ - Lê o arquivo /usuarios.yaml e importa os usuários nele listados, - com senhas e perfis. - Os usuários são criados se necessário e seus perfis ajustados. - - Os seguintes perfis no legado não correspondem a nenhum no código atual - e estão sendo **ignorados**: - - * Operador Mesa Diretora - Apenas **8 usuários**, em todas as bases, têm esse perfil - e não têm nem "Operador" nem "Operador Sessao Plenaria" - - * Operador Ordem Dia - Apenas **16 usuários**, em todas as bases, têm esse perfil - e não têm nem "Operador" nem "Operador Sessao Plenaria" - - * Operador Tabela Auxiliar - A edição das tabelas auxiliares deve ser feita por um administrador - - * Operador Lexml - Também podemos assumir que essa é uma tarefa de um administrador - """ - - ARQUIVO_USUARIOS = Path(dir_repo).child('usuarios.yaml') - with open(ARQUIVO_USUARIOS, 'r') as f: - usuarios = yaml.load(f, yaml.Loader) - # conferimos de que só há um nome de usuário - assert all(nome == dados['name'] for nome, dados in usuarios.items()) - usuarios = [ - (decode_nome(nome), - # troca senha "inicial" (que existe em alguns zopes) - # por uma inutilizável - dados['__'] if dados['__'] != 'inicial' else None, - # filtra perfis ignorados - set(dados['roles']) - IGNORADOS) - for nome, dados in usuarios.items()] - - admins = [] - for nome, senha, perfis in usuarios: - usuario = User.objects.get_or_create(username=nome)[0] - usuario.password = zope_encoded_password_to_django(senha) - for perfil in perfis: - if perfil in ADMINISTRADORES: - # todos os administradores ganham perfil "Operador Geral" - usuario.groups.add(PERFIL_LEGADO_PARA_NOVO['Operador']) - admins.append(usuario) - else: - usuario.groups.add(PERFIL_LEGADO_PARA_NOVO[perfil]) - usuario.save() - - # configura administradores - for admin in admins: - admin.is_superuser = True - admin.save() - - print('Usuários migrados com sucesso.') - print('#' * 100) - print('Uusários administradores:') - for admin in admins: - print(admin.username) - print('#' * 100) diff --git a/sapl/legacy/models.py b/sapl/legacy/models.py deleted file mode 100644 index cd6d433df..000000000 --- a/sapl/legacy/models.py +++ /dev/null @@ -1,1101 +0,0 @@ -# This is an auto-generated Django model module. -# DO NOT EDIT THIS FILE !!! - -from django.db import models - - -class AcompMateria(models.Model): - cod_cadastro = models.AutoField(primary_key=True) - cod_materia = models.IntegerField() - end_email = models.CharField(max_length=100) - txt_hash = models.CharField(max_length=8) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'acomp_materia' - unique_together = (('cod_materia', 'end_email'),) - - -class Anexada(models.Model): - cod_materia_principal = models.IntegerField() - cod_materia_anexada = models.IntegerField() - dat_anexacao = models.DateField() - dat_desanexacao = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'anexada' - unique_together = (('cod_materia_principal', 'cod_materia_anexada'),) - - -class AssuntoMateria(models.Model): - cod_assunto = models.IntegerField(primary_key=True) - des_assunto = models.CharField(max_length=200) - des_dispositivo = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'assunto_materia' - - -class AssuntoNorma(models.Model): - cod_assunto = models.AutoField(primary_key=True) - des_assunto = models.CharField(max_length=50) - des_estendida = models.CharField(max_length=250, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'assunto_norma' - - -class Autor(models.Model): - cod_autor = models.AutoField(primary_key=True) - cod_partido = models.IntegerField(blank=True, null=True) - cod_comissao = models.IntegerField(blank=True, null=True) - cod_parlamentar = models.IntegerField(blank=True, null=True) - tip_autor = models.IntegerField() - nom_autor = models.CharField(max_length=50, blank=True, null=True) - des_cargo = models.CharField(max_length=50, blank=True, null=True) - col_username = models.CharField(max_length=50, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'autor' - - -class Autoria(models.Model): - cod_autor = models.IntegerField() - cod_materia = models.IntegerField() - ind_primeiro_autor = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'autoria' - unique_together = (('cod_autor', 'cod_materia'),) - - -class CargoComissao(models.Model): - cod_cargo = models.AutoField(primary_key=True) - des_cargo = models.CharField(max_length=50) - ind_unico = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'cargo_comissao' - - -class CargoMesa(models.Model): - cod_cargo = models.AutoField(primary_key=True) - des_cargo = models.CharField(max_length=50) - ind_unico = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'cargo_mesa' - - -class Coligacao(models.Model): - cod_coligacao = models.AutoField(primary_key=True) - num_legislatura = models.IntegerField() - nom_coligacao = models.CharField(max_length=50) - num_votos_coligacao = models.IntegerField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'coligacao' - - -class Comissao(models.Model): - cod_comissao = models.AutoField(primary_key=True) - tip_comissao = models.IntegerField() - nom_comissao = models.CharField(max_length=60) - sgl_comissao = models.CharField(max_length=10) - dat_criacao = models.DateField() - dat_extincao = models.DateField(blank=True, null=True) - nom_apelido_temp = models.CharField(max_length=100, blank=True, null=True) - dat_instalacao_temp = models.DateField(blank=True, null=True) - dat_final_prevista_temp = models.DateField(blank=True, null=True) - dat_prorrogada_temp = models.DateField(blank=True, null=True) - dat_fim_comissao = models.DateField(blank=True, null=True) - nom_secretario = models.CharField(max_length=30, blank=True, null=True) - num_tel_reuniao = models.CharField(max_length=15, blank=True, null=True) - end_secretaria = models.CharField(max_length=100, blank=True, null=True) - num_tel_secretaria = models.CharField(max_length=15, blank=True, null=True) - num_fax_secretaria = models.CharField(max_length=15, blank=True, null=True) - des_agenda_reuniao = models.CharField( - max_length=100, blank=True, null=True) - loc_reuniao = models.CharField(max_length=100, blank=True, null=True) - txt_finalidade = models.TextField(blank=True, null=True) - end_email = models.CharField(max_length=100, blank=True, null=True) - ind_unid_deliberativa = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'comissao' - - -class ComposicaoColigacao(models.Model): - cod_partido = models.IntegerField() - cod_coligacao = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'composicao_coligacao' - unique_together = (('cod_partido', 'cod_coligacao'),) - - -class ComposicaoComissao(models.Model): - cod_comp_comissao = models.AutoField(primary_key=True) - cod_parlamentar = models.IntegerField() - cod_comissao = models.IntegerField() - cod_periodo_comp = models.IntegerField() - cod_cargo = models.IntegerField() - ind_titular = models.IntegerField() - dat_designacao = models.DateField() - dat_desligamento = models.DateField(blank=True, null=True) - des_motivo_desligamento = models.CharField( - max_length=150, blank=True, null=True) - obs_composicao = models.CharField(max_length=150, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'composicao_comissao' - - -class ComposicaoMesa(models.Model): - cod_parlamentar = models.IntegerField() - cod_sessao_leg = models.IntegerField() - cod_cargo = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'composicao_mesa' - unique_together = (('cod_parlamentar', 'cod_sessao_leg', 'cod_cargo'),) - - -class Dependente(models.Model): - cod_dependente = models.AutoField(primary_key=True) - tip_dependente = models.IntegerField() - cod_parlamentar = models.IntegerField() - nom_dependente = models.CharField(max_length=50) - sex_dependente = models.CharField(max_length=1) - dat_nascimento = models.DateField(blank=True, null=True) - num_cpf = models.CharField(max_length=14, blank=True, null=True) - num_rg = models.CharField(max_length=15, blank=True, null=True) - num_tit_eleitor = models.CharField(max_length=15, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'dependente' - - -class DespachoInicial(models.Model): - cod_materia = models.IntegerField() - num_ordem = models.IntegerField() - cod_comissao = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'despacho_inicial' - unique_together = (('cod_materia', 'num_ordem'),) - - -class DocumentoAcessorio(models.Model): - cod_documento = models.AutoField(primary_key=True) - cod_materia = models.IntegerField() - tip_documento = models.IntegerField() - nom_documento = models.CharField(max_length=30) - dat_documento = models.DateField(blank=True, null=True) - nom_autor_documento = models.CharField( - max_length=50, blank=True, null=True) - txt_ementa = models.TextField(blank=True, null=True) - txt_indexacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'documento_acessorio' - - -class DocumentoAcessorioAdministrativo(models.Model): - cod_documento_acessorio = models.AutoField(primary_key=True) - cod_documento = models.IntegerField() - tip_documento = models.IntegerField() - nom_documento = models.CharField(max_length=30) - nom_arquivo = models.CharField(max_length=100) - dat_documento = models.DateField(blank=True, null=True) - nom_autor_documento = models.CharField( - max_length=50, blank=True, null=True) - txt_assunto = models.TextField(blank=True, null=True) - txt_indexacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'documento_acessorio_administrativo' - - -class DocumentoAdministrativo(models.Model): - cod_documento = models.AutoField(primary_key=True) - tip_documento = models.IntegerField() - num_documento = models.IntegerField() - ano_documento = models.SmallIntegerField() - dat_documento = models.DateField() - num_protocolo = models.IntegerField(blank=True, null=True) - txt_interessado = models.CharField(max_length=50, blank=True, null=True) - cod_autor = models.IntegerField(blank=True, null=True) - num_dias_prazo = models.IntegerField(blank=True, null=True) - dat_fim_prazo = models.DateField(blank=True, null=True) - ind_tramitacao = models.IntegerField() - txt_assunto = models.TextField() - txt_observacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'documento_administrativo' - - -class ExpedienteMateria(models.Model): - cod_ordem = models.AutoField(primary_key=True) - cod_sessao_plen = models.IntegerField() - cod_materia = models.IntegerField() - dat_ordem = models.DateField() - txt_observacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - num_ordem = models.IntegerField() - txt_resultado = models.TextField(blank=True, null=True) - tip_votacao = models.IntegerField() - - class Meta: - managed = False - db_table = 'expediente_materia' - - -class ExpedienteSessaoPlenaria(models.Model): - cod_sessao_plen = models.IntegerField() - cod_expediente = models.IntegerField() - txt_expediente = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'expediente_sessao_plenaria' - unique_together = (('cod_sessao_plen', 'cod_expediente'),) - - -class Filiacao(models.Model): - dat_filiacao = models.DateField() - cod_parlamentar = models.IntegerField() - cod_partido = models.IntegerField() - dat_desfiliacao = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'filiacao' - unique_together = (('dat_filiacao', 'cod_parlamentar', 'cod_partido'),) - - -class LegislacaoCitada(models.Model): - cod_materia = models.IntegerField() - cod_norma = models.IntegerField() - des_disposicoes = models.CharField(max_length=15, blank=True, null=True) - des_parte = models.CharField(max_length=8, blank=True, null=True) - des_livro = models.CharField(max_length=7, blank=True, null=True) - des_titulo = models.CharField(max_length=7, blank=True, null=True) - des_capitulo = models.CharField(max_length=7, blank=True, null=True) - des_secao = models.CharField(max_length=7, blank=True, null=True) - des_subsecao = models.CharField(max_length=7, blank=True, null=True) - des_artigo = models.CharField(max_length=4, blank=True, null=True) - des_paragrafo = models.CharField(max_length=3, blank=True, null=True) - des_inciso = models.CharField(max_length=10, blank=True, null=True) - des_alinea = models.CharField(max_length=3, blank=True, null=True) - des_item = models.CharField(max_length=3, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'legislacao_citada' - unique_together = (('cod_materia', 'cod_norma'),) - - -class Legislatura(models.Model): - num_legislatura = models.IntegerField(primary_key=True) - dat_inicio = models.DateField() - dat_fim = models.DateField() - dat_eleicao = models.DateField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'legislatura' - - -class LexmlRegistroProvedor(models.Model): - cod_provedor = models.AutoField(primary_key=True) - id_provedor = models.IntegerField() - nom_provedor = models.CharField(max_length=255) - sgl_provedor = models.CharField(max_length=15) - adm_email = models.CharField(max_length=50, blank=True, null=True) - nom_responsavel = models.CharField(max_length=255, blank=True, null=True) - tipo = models.CharField(max_length=50) - id_responsavel = models.IntegerField(blank=True, null=True) - xml_provedor = models.TextField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'lexml_registro_provedor' - - -class LexmlRegistroPublicador(models.Model): - cod_publicador = models.AutoField(primary_key=True) - id_publicador = models.IntegerField() - nom_publicador = models.CharField(max_length=255) - adm_email = models.CharField(max_length=50, blank=True, null=True) - sigla = models.CharField(max_length=255, blank=True, null=True) - nom_responsavel = models.CharField(max_length=255, blank=True, null=True) - tipo = models.CharField(max_length=50) - id_responsavel = models.IntegerField() - - class Meta: - managed = False - db_table = 'lexml_registro_publicador' - - -class Localidade(models.Model): - cod_localidade = models.IntegerField(primary_key=True) - nom_localidade = models.CharField(max_length=50, blank=True, null=True) - nom_localidade_pesq = models.CharField( - max_length=50, blank=True, null=True) - tip_localidade = models.CharField(max_length=1, blank=True, null=True) - sgl_uf = models.CharField(max_length=2, blank=True, null=True) - sgl_regiao = models.CharField(max_length=2, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'localidade' - - -class Mandato(models.Model): - cod_mandato = models.AutoField(primary_key=True) - cod_parlamentar = models.IntegerField() - tip_afastamento = models.IntegerField(blank=True, null=True) - num_legislatura = models.IntegerField() - cod_coligacao = models.IntegerField(blank=True, null=True) - tip_causa_fim_mandato = models.IntegerField(blank=True, null=True) - dat_fim_mandato = models.DateField(blank=True, null=True) - num_votos_recebidos = models.IntegerField(blank=True, null=True) - dat_expedicao_diploma = models.DateField(blank=True, null=True) - txt_observacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'mandato' - - -class MateriaAssunto(models.Model): - cod_assunto = models.IntegerField() - cod_materia = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'materia_assunto' - unique_together = (('cod_assunto', 'cod_materia'),) - - -class MateriaLegislativa(models.Model): - cod_materia = models.AutoField(primary_key=True) - tip_id_basica = models.IntegerField() - num_protocolo = models.IntegerField(blank=True, null=True) - num_ident_basica = models.IntegerField() - ano_ident_basica = models.SmallIntegerField() - dat_apresentacao = models.DateField(blank=True, null=True) - tip_apresentacao = models.CharField(max_length=1, blank=True, null=True) - cod_regime_tramitacao = models.IntegerField() - dat_publicacao = models.DateField(blank=True, null=True) - tip_origem_externa = models.IntegerField(blank=True, null=True) - num_origem_externa = models.CharField(max_length=10, blank=True, null=True) - ano_origem_externa = models.SmallIntegerField(blank=True, null=True) - dat_origem_externa = models.DateField(blank=True, null=True) - cod_local_origem_externa = models.IntegerField(blank=True, null=True) - nom_apelido = models.CharField(max_length=50, blank=True, null=True) - num_dias_prazo = models.IntegerField(blank=True, null=True) - dat_fim_prazo = models.DateField(blank=True, null=True) - ind_tramitacao = models.IntegerField() - ind_polemica = models.IntegerField(blank=True, null=True) - des_objeto = models.CharField(max_length=150, blank=True, null=True) - ind_complementar = models.IntegerField(blank=True, null=True) - txt_ementa = models.TextField() - txt_indexacao = models.TextField(blank=True, null=True) - txt_observacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - txt_resultado = models.TextField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'materia_legislativa' - - -class MesaSessaoPlenaria(models.Model): - cod_cargo = models.IntegerField() - cod_sessao_leg = models.IntegerField() - cod_parlamentar = models.IntegerField() - cod_sessao_plen = models.IntegerField() - ind_excluido = models.IntegerField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'mesa_sessao_plenaria' - unique_together = ( - ('cod_cargo', - 'cod_sessao_leg', - 'cod_parlamentar', - 'cod_sessao_plen'), - ) - - -class NivelInstrucao(models.Model): - cod_nivel_instrucao = models.AutoField(primary_key=True) - des_nivel_instrucao = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'nivel_instrucao' - - -class NormaJuridica(models.Model): - cod_norma = models.AutoField(primary_key=True) - tip_norma = models.IntegerField() - cod_materia = models.IntegerField(blank=True, null=True) - num_norma = models.IntegerField() - ano_norma = models.SmallIntegerField() - tip_esfera_federacao = models.CharField(max_length=1) - dat_norma = models.DateField(blank=True, null=True) - dat_publicacao = models.DateField(blank=True, null=True) - des_veiculo_publicacao = models.CharField( - max_length=30, blank=True, null=True) - num_pag_inicio_publ = models.IntegerField(blank=True, null=True) - num_pag_fim_publ = models.IntegerField(blank=True, null=True) - txt_ementa = models.TextField() - txt_indexacao = models.TextField(blank=True, null=True) - txt_observacao = models.TextField(blank=True, null=True) - ind_complemento = models.IntegerField(blank=True, null=True) - cod_assunto = models.CharField(max_length=16) - dat_vigencia = models.DateField(blank=True, null=True) - timestamp = models.DateTimeField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'norma_juridica' - - -class Numeracao(models.Model): - cod_materia = models.IntegerField() - num_ordem = models.IntegerField() - tip_materia = models.IntegerField() - num_materia = models.CharField(max_length=5) - ano_materia = models.SmallIntegerField() - dat_materia = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'numeracao' - unique_together = (('cod_materia', 'num_ordem'),) - - -class Oradores(models.Model): - cod_sessao_plen = models.IntegerField() - cod_parlamentar = models.IntegerField() - num_ordem = models.IntegerField() - url_discurso = models.CharField(max_length=150, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'oradores' - unique_together = (('cod_sessao_plen', 'cod_parlamentar'),) - - -class OradoresExpediente(models.Model): - cod_sessao_plen = models.IntegerField() - cod_parlamentar = models.IntegerField() - num_ordem = models.IntegerField() - url_discurso = models.CharField(max_length=150, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'oradores_expediente' - unique_together = (('cod_sessao_plen', 'cod_parlamentar'),) - - -class OrdemDia(models.Model): - cod_ordem = models.AutoField(primary_key=True) - cod_sessao_plen = models.IntegerField() - cod_materia = models.IntegerField() - dat_ordem = models.DateField() - txt_observacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - num_ordem = models.IntegerField() - txt_resultado = models.TextField(blank=True, null=True) - tip_votacao = models.IntegerField() - - class Meta: - managed = False - db_table = 'ordem_dia' - - -class OrdemDiaPresenca(models.Model): - cod_presenca_ordem_dia = models.AutoField(primary_key=True) - cod_sessao_plen = models.IntegerField() - cod_parlamentar = models.IntegerField() - dat_ordem = models.DateField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'ordem_dia_presenca' - - -class Orgao(models.Model): - cod_orgao = models.AutoField(primary_key=True) - nom_orgao = models.CharField(max_length=60) - sgl_orgao = models.CharField(max_length=10) - ind_unid_deliberativa = models.IntegerField() - end_orgao = models.CharField(max_length=100, blank=True, null=True) - num_tel_orgao = models.CharField(max_length=50, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'orgao' - - -class Origem(models.Model): - cod_origem = models.AutoField(primary_key=True) - sgl_origem = models.CharField(max_length=10) - nom_origem = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'origem' - - -class Parecer(models.Model): - cod_relatoria = models.IntegerField() - cod_materia = models.IntegerField() - tip_conclusao = models.CharField(max_length=3, blank=True, null=True) - tip_apresentacao = models.CharField(max_length=1) - txt_parecer = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'parecer' - unique_together = (('cod_relatoria', 'cod_materia'),) - - -class Parlamentar(models.Model): - cod_parlamentar = models.AutoField(primary_key=True) - cod_nivel_instrucao = models.IntegerField(blank=True, null=True) - tip_situacao_militar = models.IntegerField(blank=True, null=True) - nom_completo = models.CharField(max_length=50) - nom_parlamentar = models.CharField(max_length=50, blank=True, null=True) - sex_parlamentar = models.CharField(max_length=1) - dat_nascimento = models.DateField(blank=True, null=True) - num_cpf = models.CharField(max_length=14, blank=True, null=True) - num_rg = models.CharField(max_length=15, blank=True, null=True) - num_tit_eleitor = models.CharField(max_length=15, blank=True, null=True) - cod_casa = models.IntegerField() - num_gab_parlamentar = models.CharField( - max_length=10, blank=True, null=True) - num_tel_parlamentar = models.CharField( - max_length=50, blank=True, null=True) - num_fax_parlamentar = models.CharField( - max_length=50, blank=True, null=True) - end_residencial = models.CharField(max_length=100, blank=True, null=True) - cod_localidade_resid = models.IntegerField(blank=True, null=True) - num_cep_resid = models.CharField(max_length=9, blank=True, null=True) - num_tel_resid = models.CharField(max_length=50, blank=True, null=True) - num_fax_resid = models.CharField(max_length=50, blank=True, null=True) - end_web = models.CharField(max_length=100, blank=True, null=True) - nom_profissao = models.CharField(max_length=50, blank=True, null=True) - end_email = models.CharField(max_length=100, blank=True, null=True) - des_local_atuacao = models.CharField(max_length=100, blank=True, null=True) - ind_ativo = models.IntegerField() - txt_biografia = models.TextField(blank=True, null=True) - ind_unid_deliberativa = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'parlamentar' - - -class Partido(models.Model): - cod_partido = models.AutoField(primary_key=True) - sgl_partido = models.CharField(max_length=9) - nom_partido = models.CharField(max_length=50) - dat_criacao = models.DateField(blank=True, null=True) - dat_extincao = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'partido' - - -class PeriodoCompComissao(models.Model): - cod_periodo_comp = models.AutoField(primary_key=True) - dat_inicio_periodo = models.DateField() - dat_fim_periodo = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'periodo_comp_comissao' - - -class Proposicao(models.Model): - cod_proposicao = models.AutoField(primary_key=True) - cod_materia = models.IntegerField(blank=True, null=True) - cod_autor = models.IntegerField() - tip_proposicao = models.IntegerField() - dat_envio = models.DateTimeField() - dat_recebimento = models.DateTimeField(blank=True, null=True) - txt_descricao = models.CharField(max_length=100) - cod_mat_ou_doc = models.IntegerField(blank=True, null=True) - dat_devolucao = models.DateTimeField(blank=True, null=True) - txt_justif_devolucao = models.CharField( - max_length=200, blank=True, null=True) - num_proposicao = models.IntegerField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'proposicao' - - -class Protocolo(models.Model): - cod_protocolo = models.AutoField(primary_key=True) - num_protocolo = models.IntegerField(blank=True, null=True) - ano_protocolo = models.SmallIntegerField() - dat_protocolo = models.DateField() - hor_protocolo = models.TimeField() - dat_timestamp = models.DateTimeField() - tip_protocolo = models.IntegerField() - tip_processo = models.IntegerField() - txt_interessado = models.CharField(max_length=60, blank=True, null=True) - cod_autor = models.IntegerField(blank=True, null=True) - txt_assunto_ementa = models.TextField(blank=True, null=True) - tip_documento = models.IntegerField(blank=True, null=True) - tip_materia = models.IntegerField(blank=True, null=True) - num_paginas = models.IntegerField(blank=True, null=True) - txt_observacao = models.TextField(blank=True, null=True) - ind_anulado = models.IntegerField() - txt_user_anulacao = models.CharField(max_length=20, blank=True, null=True) - txt_ip_anulacao = models.CharField(max_length=15, blank=True, null=True) - txt_just_anulacao = models.CharField(max_length=60, blank=True, null=True) - timestamp_anulacao = models.DateTimeField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'protocolo' - - -class RegimeTramitacao(models.Model): - cod_regime_tramitacao = models.AutoField(primary_key=True) - des_regime_tramitacao = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'regime_tramitacao' - - -class RegistroVotacao(models.Model): - cod_votacao = models.AutoField(primary_key=True) - tip_resultado_votacao = models.IntegerField() - cod_materia = models.IntegerField() - cod_ordem = models.IntegerField() - num_votos_sim = models.IntegerField() - num_votos_nao = models.IntegerField() - num_abstencao = models.IntegerField() - txt_observacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'registro_votacao' - - -class RegistroVotacaoParlamentar(models.Model): - cod_votacao = models.IntegerField() - cod_parlamentar = models.IntegerField() - ind_excluido = models.IntegerField() - vot_parlamentar = models.CharField(max_length=10) - - class Meta: - managed = False - db_table = 'registro_votacao_parlamentar' - unique_together = (('cod_votacao', 'cod_parlamentar'),) - - -class Relatoria(models.Model): - cod_relatoria = models.AutoField(primary_key=True) - cod_materia = models.IntegerField() - cod_parlamentar = models.IntegerField() - tip_fim_relatoria = models.IntegerField(blank=True, null=True) - cod_comissao = models.IntegerField(blank=True, null=True) - dat_desig_relator = models.DateField() - dat_destit_relator = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'relatoria' - - -class ReuniaoComissao(models.Model): - cod_reuniao = models.AutoField(primary_key=True) - cod_comissao = models.IntegerField() - num_reuniao = models.IntegerField() - dat_inicio_reuniao = models.DateField() - hr_inicio_reuniao = models.CharField(max_length=5, blank=True, null=True) - txt_observacao = models.TextField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'reuniao_comissao' - - -class SessaoLegislativa(models.Model): - cod_sessao_leg = models.AutoField(primary_key=True) - num_legislatura = models.IntegerField() - num_sessao_leg = models.IntegerField() - tip_sessao_leg = models.CharField(max_length=1) - dat_inicio = models.DateField() - dat_fim = models.DateField() - dat_inicio_intervalo = models.DateField(blank=True, null=True) - dat_fim_intervalo = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'sessao_legislativa' - - -class SessaoPlenaria(models.Model): - cod_sessao_plen = models.AutoField(primary_key=True) - cod_andamento_sessao = models.IntegerField(blank=True, null=True) - tip_sessao = models.IntegerField() - cod_sessao_leg = models.IntegerField() - num_legislatura = models.IntegerField() - tip_expediente = models.CharField(max_length=10) - dat_inicio_sessao = models.DateField() - dia_sessao = models.CharField(max_length=15) - hr_inicio_sessao = models.CharField(max_length=5) - hr_fim_sessao = models.CharField(max_length=5, blank=True, null=True) - num_sessao_plen = models.IntegerField() - dat_fim_sessao = models.DateField(blank=True, null=True) - url_audio = models.CharField(max_length=150, blank=True, null=True) - url_video = models.CharField(max_length=150, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'sessao_plenaria' - - -class SessaoPlenariaPresenca(models.Model): - cod_presenca_sessao = models.AutoField(primary_key=True) - cod_sessao_plen = models.IntegerField() - cod_parlamentar = models.IntegerField() - dat_sessao = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'sessao_plenaria_presenca' - - -class StatusTramitacao(models.Model): - cod_status = models.AutoField(primary_key=True) - sgl_status = models.CharField(max_length=10) - des_status = models.CharField(max_length=60) - ind_fim_tramitacao = models.IntegerField() - ind_retorno_tramitacao = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'status_tramitacao' - - -class StatusTramitacaoAdministrativo(models.Model): - cod_status = models.AutoField(primary_key=True) - sgl_status = models.CharField(max_length=10) - des_status = models.CharField(max_length=60) - ind_fim_tramitacao = models.IntegerField() - ind_retorno_tramitacao = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'status_tramitacao_administrativo' - - -class TipoAfastamento(models.Model): - tip_afastamento = models.AutoField(primary_key=True) - des_afastamento = models.CharField(max_length=50) - ind_afastamento = models.IntegerField() - ind_fim_mandato = models.IntegerField() - des_dispositivo = models.CharField(max_length=50, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_afastamento' - - -class TipoAutor(models.Model): - tip_autor = models.IntegerField(primary_key=True) - des_tipo_autor = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_autor' - - -class TipoComissao(models.Model): - tip_comissao = models.AutoField(primary_key=True) - nom_tipo_comissao = models.CharField(max_length=50) - sgl_natureza_comissao = models.CharField(max_length=1) - sgl_tipo_comissao = models.CharField(max_length=10) - des_dispositivo_regimental = models.CharField( - max_length=50, blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_comissao' - - -class TipoDependente(models.Model): - tip_dependente = models.AutoField(primary_key=True) - des_tipo_dependente = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_dependente' - - -class TipoDocumento(models.Model): - tip_documento = models.AutoField(primary_key=True) - des_tipo_documento = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_documento' - - -class TipoDocumentoAdministrativo(models.Model): - tip_documento = models.AutoField(primary_key=True) - sgl_tipo_documento = models.CharField(max_length=5) - des_tipo_documento = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_documento_administrativo' - - -class TipoExpediente(models.Model): - cod_expediente = models.AutoField(primary_key=True) - nom_expediente = models.CharField(max_length=100) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_expediente' - - -class TipoFimRelatoria(models.Model): - tip_fim_relatoria = models.AutoField(primary_key=True) - des_fim_relatoria = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_fim_relatoria' - - -class TipoMateriaLegislativa(models.Model): - tip_materia = models.AutoField(primary_key=True) - sgl_tipo_materia = models.CharField(max_length=5) - des_tipo_materia = models.CharField(max_length=50) - ind_num_automatica = models.IntegerField() - quorum_minimo_votacao = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_materia_legislativa' - - -class TipoNormaJuridica(models.Model): - tip_norma = models.AutoField(primary_key=True) - voc_lexml = models.CharField(max_length=50, blank=True, null=True) - sgl_tipo_norma = models.CharField(max_length=3) - des_tipo_norma = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_norma_juridica' - - -class TipoNumeracaoProtocolo(models.Model): - seq_tip_num_protocolo = models.AutoField(primary_key=True) - tip_numeracao_protocolo = models.IntegerField() - des_numeracao_protocolo = models.CharField(max_length=50) - dat_inicial_protocolo = models.DateTimeField() - vlr_inicial_protocolo = models.IntegerField() - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_numeracao_protocolo' - - -class TipoProposicao(models.Model): - tip_proposicao = models.AutoField(primary_key=True) - des_tipo_proposicao = models.CharField(max_length=50) - ind_mat_ou_doc = models.CharField(max_length=1) - tip_mat_ou_doc = models.IntegerField() - nom_modelo = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_proposicao' - - -class TipoResultadoVotacao(models.Model): - tip_resultado_votacao = models.AutoField(primary_key=True) - nom_resultado = models.CharField(max_length=100) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_resultado_votacao' - - -class TipoSessaoPlenaria(models.Model): - tip_sessao = models.AutoField(primary_key=True) - nom_sessao = models.CharField(max_length=30) - ind_excluido = models.IntegerField() - num_minimo = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_sessao_plenaria' - - -class SituacaoMilitar(models.Model): - tip_situacao_militar = models.IntegerField(primary_key=True) - des_tipo_situacao = models.CharField(max_length=50) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tipo_situacao_militar' - - -class Tramitacao(models.Model): - cod_tramitacao = models.AutoField(primary_key=True) - cod_status = models.IntegerField(blank=True, null=True) - cod_materia = models.IntegerField() - dat_tramitacao = models.DateField(blank=True, null=True) - cod_unid_tram_local = models.IntegerField(blank=True, null=True) - dat_encaminha = models.DateField(blank=True, null=True) - cod_unid_tram_dest = models.IntegerField(blank=True, null=True) - ind_ult_tramitacao = models.IntegerField() - ind_urgencia = models.IntegerField() - sgl_turno = models.CharField(max_length=1, blank=True, null=True) - txt_tramitacao = models.TextField(blank=True, null=True) - dat_fim_prazo = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tramitacao' - - -class TramitacaoAdministrativo(models.Model): - cod_tramitacao = models.AutoField(primary_key=True) - cod_documento = models.IntegerField() - dat_tramitacao = models.DateField(blank=True, null=True) - cod_unid_tram_local = models.IntegerField(blank=True, null=True) - dat_encaminha = models.DateField(blank=True, null=True) - cod_unid_tram_dest = models.IntegerField(blank=True, null=True) - cod_status = models.IntegerField(blank=True, null=True) - ind_ult_tramitacao = models.IntegerField() - txt_tramitacao = models.TextField(blank=True, null=True) - dat_fim_prazo = models.DateField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'tramitacao_administrativo' - - -class UnidadeTramitacao(models.Model): - cod_unid_tramitacao = models.AutoField(primary_key=True) - cod_comissao = models.IntegerField(blank=True, null=True) - cod_orgao = models.IntegerField(blank=True, null=True) - cod_parlamentar = models.IntegerField(blank=True, null=True) - ind_excluido = models.IntegerField() - - class Meta: - managed = False - db_table = 'unidade_tramitacao' - - -class VinculoNormaJuridica(models.Model): - cod_vinculo = models.AutoField(primary_key=True) - cod_norma_referente = models.IntegerField() - cod_norma_referida = models.IntegerField() - tip_vinculo = models.CharField(max_length=1, blank=True, null=True) - ind_excluido = models.CharField(max_length=1) - - class Meta: - managed = False - db_table = 'vinculo_norma_juridica' diff --git a/sapl/legacy/router.py b/sapl/legacy/router.py deleted file mode 100644 index 1aa51a46b..000000000 --- a/sapl/legacy/router.py +++ /dev/null @@ -1,22 +0,0 @@ -class LegacyRouter: - - def db_for_read(self, model, **hints): - if model._meta.app_label == 'legacy': - return 'legacy' - return None - - def db_for_write(self, model, **hints): - if model._meta.app_label == 'legacy': - return 'legacy' - return None - - def allow_relation(self, obj1, obj2, **hints): - if obj1._meta.app_label == 'legacy' \ - and obj2._meta.app_label == 'legacy': - return True - return None - - def allow_migrate(self, db, app_label, model_name=None, **hints): - if app_label == 'legacy': - return False - return None diff --git a/sapl/legacy/run_legacy_tests.sh b/sapl/legacy/run_legacy_tests.sh deleted file mode 100755 index 6b7491e81..000000000 --- a/sapl/legacy/run_legacy_tests.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -# All tests under this directory are excluded in default pytest.ini -# To run them use this script in this directory - -py.test --ds=sapl.legacy_migration_settings diff --git a/sapl/legacy/scripts/.flake8 b/sapl/legacy/scripts/.flake8 deleted file mode 100644 index 977657542..000000000 --- a/sapl/legacy/scripts/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -ignore = E501 - diff --git a/sapl/legacy/scripts/__init__.py b/sapl/legacy/scripts/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/sapl/legacy/scripts/exporta_zope/.gitignore b/sapl/legacy/scripts/exporta_zope/.gitignore deleted file mode 100644 index 11c2f1d6b..000000000 --- a/sapl/legacy/scripts/exporta_zope/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -Data*.fs* -sapl_documentos -XSLT diff --git a/sapl/legacy/scripts/exporta_zope/dump30.py b/sapl/legacy/scripts/exporta_zope/dump30.py deleted file mode 100644 index 471bef4e0..000000000 --- a/sapl/legacy/scripts/exporta_zope/dump30.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- - -from exporta_zope import (br, dump_folder, dump_propriedades, dump_usuarios, - get_app, logando_nao_identificados) - - -def dump_sapl30(): - """Extrai dados do zope de um sapl 3.0, que, ao que tudo indica: - * não possui a pasta XSLT - * usa um mountpoint separado para os documentos - * usa encoding utf-8 (ao invés de iso-8859-1) - """ - destino = '../../../../media' - data_fs_path = destino + '/Data.fs' - docs_path = destino + '/DocumentosSapl.fs' - - try: - app, close_db = get_app(data_fs_path) - sapl = br(app['sapl']) - dump_usuarios(sapl, destino) - finally: - close_db() - - try: - app, close_db = get_app(docs_path) - docs = br(app['sapl_documentos']) - with logando_nao_identificados(): - dump_folder(docs, destino) - dump_propriedades(docs, destino, 'utf-8') - finally: - close_db() diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py deleted file mode 100755 index 36c570faa..000000000 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ /dev/null @@ -1,498 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# IMPORTANTE: -# Esse script precisa rodar em python 2 -# e depende apenas do descrito no arquivo requiments.txt - -import cStringIO -import hashlib -import mimetypes -import os -import sys -from collections import defaultdict -from contextlib import contextmanager -from functools import partial -from os.path import exists - -import git -import magic -import yaml -import ZODB.DB -import ZODB.FileStorage -from unipath import Path -from ZODB.broken import Broken -from ZODB.POSException import POSKeyError - -from variaveis_comuns import DIR_DADOS_MIGRACAO, TAG_ZOPE - -EXTENSOES = { - # docs - 'application/msword': '.doc', - 'application/pdf': '.pdf', - 'application/vnd.oasis.opendocument.text': '.odt', - 'application/vnd.ms-excel': '.xls', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx', # noqa - 'application/vnd.oasis.opendocument.text-template': '.ott', - 'application/vnd.ms-powerpoint': '.ppt', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx', # noqa - 'application/vnd.oasis.opendocument.spreadsheet': '.ods', - 'application/vnd.openxmlformats-officedocument.presentationml.presentation': '.pptx', # noqa - 'application/vnd.oasis.opendocument.graphics': '.odg', - - # incertos... associamos a extensão mais provável - 'application/vnd.ms-office': '.doc', - 'text/x-c++': '.cpp', - - # outros - 'application/xml': '.xml', - 'text/xml': '.xml', - 'application/zip': '.zip', - 'application/x-rar': '.rar', - 'application/x-dosexec': '.exe', - 'message/rfc822': '.mht', - 'text/richtext': '.rtx', - 'application/gzip': '.gz', - 'image/vnd.dwg': '*.dwg', - - # media - 'image/jpeg': '.jpeg', - 'image/png': '.png', - 'image/gif': '.gif', - 'text/html': '.html', - 'text/rtf': '.rtf', - 'text/x-python': '.py', - 'text/plain': '.txt', - 'SDE-Document': '.xml', - 'image/tiff': '.tiff', - 'application/tiff': '.tiff', - 'audio/x-wav': '.wav', - 'video/mp4': '.mp4', - 'image/x-icon': '.ico', - 'image/x-ms-bmp': '.bmp', - 'video/x-ms-asf': '.asf', - 'audio/mpeg': '.mp3', - 'video/x-flv': '.flv', - 'video/quicktime': '.mov', - - # sem extensao - 'application/octet-stream': '', # binário - 'inode/x-empty': '', # vazio - 'application/x-empty': '', # vazio - 'text/x-unknown-content-type': '', # desconhecido - 'application/CDFV2-unknown': '', # desconhecido -} - - -def br(obj): - if isinstance(obj, Broken): - return obj.__Broken_state__ - else: - return obj - - -def guess_extension(fullname, buffer): - # um corte de apenas 1024 impediu a detecção correta de .docx - mime = magic.from_buffer(buffer, mime=True) - extensao = EXTENSOES.get(mime) - if extensao is not None: - return extensao - else: - possibilidades = '\n'.join( - [" '{}': '{}',".format(mime, ext) - for ext in mimetypes.guess_all_extensions(mime)]) - print('''Extensão não conhecida para o arquivo: {} - e mimetype: {} - Algumas possibilidades são: - {} - Atualize o código do dicionário EXTENSOES! - '''.format(fullname, mime, possibilidades) - ) - return '.DESCONHECIDO.{}'.format(mime.replace('/', '__')) - - -CONTEUDO_ARQUIVO_CORROMPIDO = 'ARQUIVO CORROMPIDO' - - -def get_conteudo_file(doc): - # A partir daqui usamos dict.pop('...') nos __Broken_state__ - # para contornar um "vazamento" de memória que ocorre - # ao percorrer a árvore de objetos - # - # Imaginamos que, internamente, o ZODB está guardando referências - # para os objetos Broken criados e não conseguimos identificar como. - # - # Essa medida descarta quase todos os dados retornados - # e só funciona na primeira passagem - try: - pdata = br(doc.pop('data')) - if isinstance(pdata, str): - # Retrocedemos se pdata ja eh uma str (necessario em Images) - doc['data'] = pdata - pdata = doc - - output = cStringIO.StringIO() - while pdata: - output.write(pdata.pop('data')) - pdata = br(pdata.pop('next', None)) - - return output.getvalue() - except POSKeyError: - return CONTEUDO_ARQUIVO_CORROMPIDO - - -def dump_file(doc, path, salvar, get_conteudo=get_conteudo_file): - name = doc['__name__'] - fullname = os.path.join(path, name) - conteudo = get_conteudo(doc) - if conteudo == CONTEUDO_ARQUIVO_CORROMPIDO: - fullname = fullname + '_CORROMPIDO' - print('ATENÇÃO: arquivo corrompido: {}'.format(fullname)) - if conteudo: - # pula arquivos vazios - salvar(fullname, conteudo) - return name - - -def get_conteudo_dtml_method(doc): - return doc['raw'] - - -def print_msg_poskeyerror(id): - print('#' * 80) - print('#' * 80) - print('ATENÇÃO: DIRETÓRIO corrompido: {}'.format(id)) - print('#' * 80) - print('#' * 80) - - -def enumerate_by_key_list(folder, key_list, type_key): - for entry in folder.get(key_list, []): - id, meta_type = entry['id'], entry[type_key] - try: - obj = folder.get(id, None) - except POSKeyError: - print_msg_poskeyerror(id) - else: - yield id, obj, meta_type - - -enumerate_folder = partial(enumerate_by_key_list, - key_list='_objects', type_key='meta_type') - -enumerate_properties = partial(enumerate_by_key_list, - key_list='_properties', type_key='type') - - -def enumerate_btree(folder): - contagem_esperada = folder['_count'].value - tree = folder['_tree'] - contagem_real = 0 # para o caso em que não haja itens - try: - for contagem_real, (id, obj) in enumerate(tree.iteritems(), start=1): - meta_type = type(obj).__name__ - yield id, obj, meta_type - except POSKeyError: - print_msg_poskeyerror(folder['id']) - # verificação de consistência - if contagem_esperada != contagem_real: - print('ATENÇÃO: contagens diferentes na btree: ' - '{} esperada: {} real: {}'.format(folder['title'], - contagem_esperada, - contagem_real)) - - -nao_identificados = defaultdict(list) - - -@contextmanager -def logando_nao_identificados(): - nao_identificados.clear() - yield - if nao_identificados: - print('#' * 80) - print('#' * 80) - print('FORAM ENCONTRADOS ARQUIVOS DE FORMATO NÃO IDENTIFICADO!!!') - print('REFAÇA A EXPORTAÇÃO\n') - print(nao_identificados) - print('#' * 80) - print('#' * 80) - - -def dump_folder(folder, path, salvar, mtimes, enum=enumerate_folder): - name = folder['id'] - path = os.path.join(path, name) - if not exists(path): - os.makedirs(path) - for id, obj, meta_type in enum(folder): - # pula pastas *_old (presentes em várias bases) - if id.endswith('_old') and meta_type in ['Folder', 'BTreeFolder2']: - continue - dump = DUMP_FUNCTIONS.get(meta_type, '?') - if dump == '?': - nao_identificados[meta_type].append(path + '/' + id) - elif dump: - if isinstance(dump, partial) and dump.func == dump_folder: - try: - dump(br(obj), path, salvar, mtimes) - except POSKeyError as e: - print_msg_poskeyerror(id) - continue - else: - # se o objeto for mais recente que o da última exportação - mtime = obj._p_mtime - fullname = os.path.join(path, id) - if mtime > mtimes.get(fullname, 0): - id_interno = dump(br(obj), path, salvar) - assert id == id_interno - mtimes[fullname] = mtime - return name - - -def decode_iso8859(obj): - return obj.decode('iso8859-1') if isinstance(obj, str) else obj - - -def read_sde(element): - - def read_properties(): - for id, obj, meta_type in enumerate_properties(element): - yield id, decode_iso8859(br(obj)) - - def read_children(): - for id, obj, meta_type in enumerate_folder(element): - assert meta_type in ['SDE-Document-Element', - 'SDE-Template-Element', - 'SDE-Template-Link', - 'SDE-Template-Attribute', - 'Script (Python)', - ] - if meta_type != 'Script (Python)': - # ignoramos os scrips python de eventos dos templates - yield {'id': id, - 'meta_type': meta_type, - 'dados': read_sde(br(obj))} - - data = dict(read_properties()) - children = list(read_children()) - if children: - data['children'] = children - return data - - -def save_as_yaml(path, name, obj, salvar): - fullname = os.path.join(path, name) - conteudo = yaml.safe_dump(obj, allow_unicode=True) - salvar(fullname, conteudo) - - -def dump_sde(strdoc, path, salvar, tipo): - id = strdoc['id'] - sde = read_sde(strdoc) - save_as_yaml(path, '{}.{}.yaml'.format(id, tipo), sde, salvar) - return id - - -DUMP_FUNCTIONS = { - 'File': dump_file, - 'Image': dump_file, - 'DTML Method': partial(dump_file, - get_conteudo=get_conteudo_dtml_method), - 'DTMLMethod': partial(dump_file, - get_conteudo=get_conteudo_dtml_method), - 'Folder': partial(dump_folder, enum=enumerate_folder), - 'BTreeFolder2': partial(dump_folder, enum=enumerate_btree), - 'SDE-Document': partial(dump_sde, tipo='sde.document'), - 'StrDoc': partial(dump_sde, tipo='sde.document'), - 'SDE-Template': partial(dump_sde, tipo='sde.template'), - - # explicitamente ignorados - 'ZCatalog': None, - 'Dumper': None, - 'CachingPolicyManager': None, -} - - -def get_app(data_fs_path): - storage = ZODB.FileStorage.FileStorage(data_fs_path, read_only=True) - db = ZODB.DB(storage) - connection = db.open() - root = connection.root() - app = br(root['Application']) - - def close_db(): - db.close() - - return app, close_db - - -def find_sapl(app): - ids_meta_types = [(obj['id'], obj['meta_type']) for obj in app['_objects']] - # estar ordenado é muito importante para que a busca dê prioridade - # a um id "cm_zzz" antes do id "sapl" - for id, meta_type in sorted(ids_meta_types): - if id.startswith('cm_') and meta_type == 'Folder': - cm_zzz = br(app[id]) - return find_sapl(cm_zzz) - elif id == 'sapl' and meta_type in ['SAPL', 'Folder']: - sapl = br(app['sapl']) - return sapl - - -def detectar_encoding(fonte): - desc = magic.from_buffer(fonte) - for termo, enc in [('ISO-8859', 'latin1'), ('UTF-8', 'utf-8')]: - if termo in desc: - return enc - return None - - -def autodecode(fonte): - if isinstance(fonte, str): - enc = detectar_encoding(fonte) - return fonte.decode(enc) if enc else fonte - else: - return fonte - - -def dump_propriedades(docs, path, salvar): - props_sapl = br(docs['props_sapl']) - ids = [p['id'] for p in props_sapl['_properties']] - props = {id: props_sapl[id] for id in ids} - props = {id: autodecode(p) for id, p in props.items()} - save_as_yaml(path, 'sapl_documentos/propriedades.yaml', props, salvar) - - -def dump_usuarios(sapl, path, salvar): - users = br(br(sapl['acl_users'])['data']) - users = {autodecode(k): br(v) for k, v in users['data'].items()} - for dados in users.values(): - dados['name'] = autodecode(dados['name']) - save_as_yaml(path, 'usuarios.yaml', users, salvar) - - -def _dump_sapl(data_fs_path, documentos_fs_path, destino, salvar, mtimes): - assert exists(data_fs_path) - assert exists(documentos_fs_path) - # precisamos trabalhar com strings e não Path's para as comparações de mtimes - data_fs_path, documentos_fs_path, destino = map(str, ( - data_fs_path, documentos_fs_path, destino)) - - app, close_db = get_app(data_fs_path) - try: - sapl = find_sapl(app) - # extrai usuários com suas senhas e perfis - dump_usuarios(sapl, destino, salvar) - - # extrai folhas XSLT (primeira tentativa) - if 'XSLT' in sapl: - dump_folder(br(sapl['XSLT']), destino, salvar, mtimes) - - finally: - close_db() - - app, close_db = get_app(documentos_fs_path) - - try: - sapl = find_sapl(app) - if sapl == {'id': 'sapl'}: - # em algumas instalações sapl_documentos está direto na raiz - docs = br(app['sapl_documentos']) - else: - # caso mais comum - docs = br(sapl['sapl_documentos']) - - # extrai folhas XSLT (segunda tentativa) - if 'XSLT' in sapl: - dump_folder(br(sapl['XSLT']), destino, salvar, mtimes) - - # extrai documentos - with logando_nao_identificados(): - dump_folder(docs, destino, salvar, mtimes) - dump_propriedades(docs, destino, salvar) - finally: - close_db() - - -def repo_execute(repo, cmd, *args): - return repo.git.execute(cmd.split() + list(args)) - - -def ajusta_extensao(fullname, conteudo): - base, extensao = os.path.splitext(fullname) - if extensao not in ['.xsl', '.xslt', '.yaml', '.css']: - extensao = guess_extension(fullname, conteudo) - return base + extensao, extensao - - -def build_salvar(repo): - - def salvar(fullname, conteudo): - fullname, extensao = ajusta_extensao(fullname, conteudo) - - # ajusta caminhos XSLT p conteúdos relacionados ao SDE - if extensao in ['.xsl', '.xslt', '.xml']: - conteudo = conteudo.replace('"XSLT/HTML', '"/XSLT/HTML') - - if exists(fullname): - # destrava arquivo pré-existente (o conteúdo mudou) - repo_execute(repo, 'git annex unlock', fullname) - with open(fullname, 'w') as arq: - arq.write(conteudo) - print(fullname) - - return salvar - - -def dump_sapl(sigla): - sigla = sigla[-3:] # ignora prefixo (por ex. 'sapl_cm_') - data_fs_path, documentos_fs_path = [ - DIR_DADOS_MIGRACAO.child( - 'datafs', '{}_cm_{}.fs'.format(prefixo, sigla)) - for prefixo in ('Data', 'DocumentosSapl')] - - assert exists(data_fs_path), 'Origem não existe: {}'.format(data_fs_path) - if not exists(documentos_fs_path): - documentos_fs_path = data_fs_path - - nome_banco_legado = 'sapl_cm_{}'.format(sigla) - destino = DIR_DADOS_MIGRACAO.child('repos', nome_banco_legado) - destino.mkdir(parents=True) - repo = git.Repo.init(destino) - if TAG_ZOPE in repo.tags: - print('{}: A exportação de documentos já está feita -- abortando'.format(sigla)) - return - - repo_execute(repo, 'git annex init') - repo_execute(repo, 'git config annex.thin true') - - salvar = build_salvar(repo) - try: - finalizado = False - arq_mtimes = Path(repo.working_dir, 'mtimes.yaml') - mtimes = yaml.load( - arq_mtimes.read_file(), - yaml.Loader - ) if arq_mtimes.exists() else {} - _dump_sapl(data_fs_path, documentos_fs_path, destino, salvar, mtimes) - finalizado = True - finally: - # grava mundaças - repo_execute(repo, 'git annex add sapl_documentos') - arq_mtimes.write_file(yaml.safe_dump(mtimes, allow_unicode=True)) - repo.git.add(A=True) - # atualiza repo - if 'master' not in repo.heads or repo.index.diff('HEAD'): - # se de fato existe mudança - status = 'completa' if finalizado else 'parcial' - repo.index.commit(u'Exportação do zope {}'.format(status)) - if finalizado: - repo.git.execute('git tag -f'.split() + [TAG_ZOPE]) - - -if __name__ == "__main__": - if len(sys.argv) == 2: - sigla = sys.argv[1] - dump_sapl(sigla) - else: - print('Uso: python exporta_zope ') diff --git a/sapl/legacy/scripts/exporta_zope/requirements.txt b/sapl/legacy/scripts/exporta_zope/requirements.txt deleted file mode 100644 index 69305576b..000000000 --- a/sapl/legacy/scripts/exporta_zope/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# ZODB version 3.7.4 -ZODB==5.3.0 -PyYAML -Unipath -GitPython -pyaml -python-magic -ipython diff --git a/sapl/legacy/scripts/exporta_zope/variaveis_comuns.py b/sapl/legacy/scripts/exporta_zope/variaveis_comuns.py deleted file mode 100644 index e773f0717..000000000 --- a/sapl/legacy/scripts/exporta_zope/variaveis_comuns.py +++ /dev/null @@ -1,4 +0,0 @@ -from unipath import Path - -DIR_DADOS_MIGRACAO = Path('~/migracao_sapl/').expand() -TAG_ZOPE = 'zope' diff --git a/sapl/legacy/scripts/migra_dbs.sh b/sapl/legacy/scripts/migra_dbs.sh deleted file mode 100755 index 891263d40..000000000 --- a/sapl/legacy/scripts/migra_dbs.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -# rodar esse script na raiz do projeto - - -if [ $# -ge 1 ]; then - # mysql com senha - parallel -eta --verbose -j+0 ./sapl/legacy/scripts/migra_um_db.sh :::: <(mysql -u $1 -p$2 -e 'show databases;' | grep '^sapl_') ::: $1 ::: $2 -elif [ $# -ge 0 ]; then - # mysql sem senha - parallel -eta --verbose -j+0 ./sapl/legacy/scripts/migra_um_db.sh :::: <(mysql -u $1 -e 'show databases;' | grep '^sapl_') ::: $1 -else - echo "USO:" - echo " $0 [senha mysql]" -fi; \ No newline at end of file diff --git a/sapl/legacy/scripts/migra_um_db.sh b/sapl/legacy/scripts/migra_um_db.sh deleted file mode 100755 index 20556ae18..000000000 --- a/sapl/legacy/scripts/migra_um_db.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -# rodar esse script na raiz do projeto -if [ $# -eq 1 ]; then - - DIR_MIGRACAO=~/migracao_sapl - - DATE=$(date +%Y-%m-%d) - DIR_LOGS=$DIR_MIGRACAO/logs/$DATE - mkdir -p $DIR_LOGS - - LOG="$DIR_LOGS/$1.migracao.log" - rm -f $LOG - - echo "########################################" | tee -a $LOG - echo "MIGRANDO BANCO $1" | tee -a $LOG - echo "########################################" | tee -a $LOG - echo >> $LOG - - echo "--- MIGRACAO ---" | tee -a $LOG - echo >> $LOG - DATABASE_NAME=$1 ./manage.py migracao_25_31 --settings sapl.legacy_migration_settings 2>&1 | tee -a $LOG - echo >> $LOG -else - echo "USO:" - echo " $0 " -fi; diff --git a/sapl/legacy/scripts/normaliza_dump_mysql.py b/sapl/legacy/scripts/normaliza_dump_mysql.py deleted file mode 100755 index a56d74b3a..000000000 --- a/sapl/legacy/scripts/normaliza_dump_mysql.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python -import re -import sys - -from unipath import Path - -cabecalho = ''' -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - -/*!40000 DROP DATABASE IF EXISTS `{banco}`*/; - -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{banco}` /*!40100 DEFAULT CHARACTER SET latin1 */; - -USE `{banco}`; - -''' - - -def normaliza_dump_mysql(nome_arquivo): - arquivo = Path(nome_arquivo).expand() - banco = arquivo.stem - conteudo = arquivo.read_file() - inicio = re.finditer('--\n-- Table structure for table .*\n--\n', conteudo) - inicio = next(inicio).start() - conteudo = cabecalho.format(banco=banco) + conteudo[inicio:] - arquivo.write_file(conteudo) - - -if __name__ == "__main__": - nome_aquivo = sys.argv[1] - normaliza_dump_mysql(nome_aquivo) diff --git a/sapl/legacy/scripts/recria_dbs_postgres.sh b/sapl/legacy/scripts/recria_dbs_postgres.sh deleted file mode 100755 index a5eab1ed7..000000000 --- a/sapl/legacy/scripts/recria_dbs_postgres.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# (Re)cria todos os bancos postgres para migração -# cria um banco postgres (de mesmo nome) para cada banco mysql cujo nome começa com "sapl_" - -if [ $# -eq 2 ]; then - parallel --verbose -j+0 ./recria_um_db_postgres.sh :::: <(mysql -u $1 -p$2 -e 'show databases;' | grep '^sapl_' | grep -v '_copy$') -else - echo "USO:" - echo " $0 [usuário mysql] [senha mysql]" -fi; \ No newline at end of file diff --git a/sapl/legacy/scripts/recria_um_db_postgres.sh b/sapl/legacy/scripts/recria_um_db_postgres.sh deleted file mode 100755 index a98056f13..000000000 --- a/sapl/legacy/scripts/recria_um_db_postgres.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -# (Re)cria um db postgres -# uso: recria_um_db_postgres - -set -e # Exit immediately if a command exits with a non-zero status - -echo "Database $1" -sudo -u postgres psql -c "drop DATABASE if exists $1" -sudo -u postgres psql -c "CREATE DATABASE $1 WITH OWNER = sapl ENCODING = 'UTF8' TABLESPACE = pg_default LC_COLLATE = 'pt_BR.UTF-8' LC_CTYPE = 'pt_BR.UTF-8' CONNECTION LIMIT = -1 TEMPLATE template0;" - - -echo "--- DJANGO MIGRATE ---" | tee -a $LOG -DATABASE_NAME=$1 ./manage.py migrate --settings sapl.legacy_migration_settings - diff --git a/sapl/legacy/scripts/ressuscita_dependencias.py b/sapl/legacy/scripts/ressuscita_dependencias.py deleted file mode 100644 index e45143567..000000000 --- a/sapl/legacy/scripts/ressuscita_dependencias.py +++ /dev/null @@ -1,427 +0,0 @@ -from collections import OrderedDict -from textwrap import dedent - -import texttable -import yaml -from unipath import Path - -from sapl.legacy.migracao_dados import (PROPAGACOES_DE_EXCLUSAO, - campos_novos_para_antigos, exec_legado, - get_arquivo_ajustes_pre_migracao, - models_novos_para_antigos) -from sapl.legacy_migration_settings import (DIR_DADOS_MIGRACAO, DIR_REPO, - NOME_BANCO_LEGADO) - - -def stripsplit(ll): - return [l.split() for l in ll.strip().splitlines()] - - -def _tab_legado(model): - return models_novos_para_antigos[model]._meta.db_table - - -fks_legado = { - (_tab_legado(m), campos_novos_para_antigos[f]): _tab_legado(f.related_model) # noqa - for m in models_novos_para_antigos - for f in m._meta.fields - if f in campos_novos_para_antigos and f.related_model} - -# acrescenta mapeamentos que não existem em campos_novos_para_antigos -for tabela_origem, campo, tabela_destino in [ - ['autor', 'cod_parlamentar', 'parlamentar'], - ['autor', 'cod_comissao', 'comissao'], - ['autor', 'cod_partido', 'partido']]: - fks_legado[(tabela_origem, campo)] = tabela_destino - - -urls = ''' -autor /sistema/autor -cargo_comissao /sistema/comissao/cargo -legislatura /sistema/parlamentar/legislatura -materia_legislativa /materia -norma_juridica /norma -parlamentar /parlamentar -sessao_legislativa /sistema/mesa-diretora/sessao-legislativa -sessao_plenaria /sessao -status_tramitacao /sistema/materia/status-tramitacao -tipo_autor /sistema/autor/tipo -tipo_expediente /sistema/sessao-plenaria/tipo-expediente -tipo_proposicao /sistema/proposicao/tipo -tipo_resultado_votacao /sistema/sessao-plenaria/tipo-resultado-votacao -unidade_tramitacao /sistema/materia/unidade-tramitacao -tipo_documento /sistema/materia/tipo-documento -orgao /sistema/materia/orgao -tipo_sessao_plenaria /sistema/sessao-plenaria/tipo -cargo_mesa /sistema/mesa-diretora/cargo-mesa -documento_administrativo /docadm -tipo_materia_legislativa /sistema/materia/tipo -tipo_norma_juridica /sistema/norma/tipo -comissao /comissao -assunto_materia /sistema/assunto-materia -coligacao /sistema/coligacao -nivel_instrucao /sistema/parlamentar/nivel-instrucao -partido /sistema/parlamentar/partido -regime_tramitacao /sistema/materia/regime-tramitacao -tipo_comissao /sistema/comissao/tipo -tipo_documento_administrativo /sistema/tipo-documento-adm -registro_votacao /admin/sessao/registrovotacao -tipo_dependente /sistema/parlamentar/tipo-dependente -origem /sistema/materia/origem -documento_acessorio /materia/documentoacessorio -tipo_fim_relatoria /sistema/materia/tipo-fim-relatoria -tipo_situacao_militar /sistema/parlamentar/tipo-militar -''' -urls = dict(stripsplit(urls)) - - -def get_tabela_campo_tipo_proposicao(tip_proposicao): - [(ind_mat_ou_doc,)] = exec_legado(''' - select ind_mat_ou_doc from tipo_proposicao where tip_proposicao = {}; - '''.format(tip_proposicao)) - if ind_mat_ou_doc == 'M': - return 'tipo_materia_legislativa', 'tip_materia' - elif ind_mat_ou_doc == 'D': - return 'tipo_documento', 'tip_documento' - else: - raise(Exception('ind_mat_ou_doc inválido')) - - -CAMPOS_ORIGEM_PARA_ALVO = { - 'cod_unid_tram_dest': 'cod_unid_tramitacao', - 'cod_unid_tram_local': 'cod_unid_tramitacao', - 'tip_id_basica': 'tip_materia', - 'cod_local_origem_externa': 'cod_origem', -} - - -def get_excluido(fk): - tabela_origem, campo, valor = [fk[k] for k in ('tabela', 'campo', 'valor')] - - if tabela_origem == 'tipo_proposicao': - tip_proposicao = fk['pk']['tip_proposicao'] - tabela_alvo, campo = get_tabela_campo_tipo_proposicao(tip_proposicao) - elif tabela_origem == 'proposicao' and campo == 'cod_mat_ou_doc': - [(ind_mat_ou_doc,)] = exec_legado(''' - select ind_mat_ou_doc from - proposicao p inner join tipo_proposicao t - on p.tip_proposicao = t.tip_proposicao - where cod_proposicao = {}; - '''.format(fk['pk']['cod_proposicao'])) - if ind_mat_ou_doc == 'M': - tabela_alvo, campo = 'materia_legislativa', 'cod_materia' - elif ind_mat_ou_doc == 'D': - tabela_alvo, campo = 'documento_acessorio', 'cod_documento' - else: - raise(Exception('ind_mat_ou_doc inválido')) - else: - tabela_alvo = fks_legado[(tabela_origem, campo)] - - # troca nome de campo pelo correspondente na tabela alvo - campo = CAMPOS_ORIGEM_PARA_ALVO.get(campo, campo) - - sql = 'select ind_excluido, t.* from {} t where {} = {}'.format( - tabela_alvo, campo, valor) - res = list(exec_legado(sql)) - return tabela_origem, campo, valor, tabela_alvo, res - - -def get_desc_materia(cod_materia): - sql = ''' - select t.sgl_tipo_materia, t.des_tipo_materia, - m.num_ident_basica, m.ano_ident_basica - from materia_legislativa m inner join tipo_materia_legislativa t - on m.tip_id_basica = t.tip_materia - where cod_materia = {}; - '''.format(cod_materia) - return list(exec_legado(sql))[0] - - -def get_link_proposicao(cod_proposicao, slug): - url_base = get_url(slug) - return 'http://{}/cadastros/proposicao/proposicao_mostrar_proc?cod_proposicao={}'.format( # noqa - url_base, cod_proposicao) - - -def get_apaga_materias_de_proposicoes(fks, slug): - refs_materias = [['id proposicao', 'sigla tipo matéria', - 'tipo matéria', 'número matéria', 'ano matéria']] - sqls = [] - cods_proposicoes = [] - - for fk in fks: - cod_proposicao = fk['pk']['cod_proposicao'] - cods_proposicoes.append(cod_proposicao) - assert fk['campo'] == 'cod_materia' - up = 'update proposicao set cod_materia = NULL where cod_proposicao = {};' # noqa - refs_materias.append( - [cod_proposicao, *get_desc_materia(fk['valor'])]) - sqls.append(up.format(cod_proposicao)) - - table = texttable.Texttable() - table.set_cols_width([10, 10, 50, 10, 10]) - table.set_deco(table.VLINES | table.HEADER) - table.add_rows(refs_materias) - - links = '\n'.join([get_link_proposicao(p, slug) - for p in cods_proposicoes]) - sqls = '\n'.join(sqls) - if not sqls: - return '' - else: - return ''' -/* REFERÊNCIAS A MATÉRIAS APAGADAS DE PROPOSIÇÕES - -ATENÇÃO - -As seguintes proposições apontaram no passado para matérias -e esses apontamentos foram em algum momento retirados. - -Elas foram migradas da forma com estão agora: sem apontar para nenhuma matéria. -Entretanto, talvez você deseje rever esses apontamentos. - -Segue então uma lista dos apontamentos anteriores que detectamos. - -{} - -Para facilitar sua conferência, seguem os links para as proposições envolvidas: - -{} - -*/ - -{} - - '''.format(table.draw(), links, sqls) - - -def get_dependencias_a_ressuscitar(slug): - ocorrencias = yaml.load( - Path(DIR_REPO.child('ocorrencias.yaml').read_file()), - yaml.Loader - ) - fks_faltando = ocorrencias.get('fk') - if not fks_faltando: - return [], [], [] - - proposicoes_para_materia = [ - fk for fk in fks_faltando - if fk['tabela'] == 'proposicao' and fk['campo'] == 'cod_materia'] - - preambulo = get_apaga_materias_de_proposicoes( - proposicoes_para_materia, slug) - - propagacoes = {(o, c) for t, o, c in PROPAGACOES_DE_EXCLUSAO} - - fks_faltando = [fk for fk in fks_faltando - if fk not in proposicoes_para_materia - and (fk['tabela'], fk['campo']) not in propagacoes] - - excluidos = [get_excluido(fk) for fk in fks_faltando] - desexcluir, criar = [ - set([(tabela_alvo, campo, valor) - for tabela_origem, campo, valor, tabela_alvo, res in excluidos - if condicao(res)]) - for condicao in ( - # o registro existe e ind_excluido == 1 - lambda res: res and res[0][0] == 1, - # o registro não existe - lambda res: not res - )] - return preambulo, desexcluir, criar - - -# deve ser idempotente pois é usada na criação de autor -# por isso o ON DUPLICATE KEY UPDATE -SQL_INSERT_TIPO_AUTOR = ''' - insert into tipo_autor (tip_autor, des_tipo_autor, ind_excluido) - values ({}, "DESCONHECIDO", 0) ON DUPLICATE KEY UPDATE ind_excluido = 0; - ''' - -# deve ser idempotente pois é usada na criação de comissao -# por isso o ON DUPLICATE KEY UPDATE -SQL_INSERT_TIPO_COMISSAO = ''' - insert into tipo_comissao (tip_comissao, nom_tipo_comissao, sgl_natureza_comissao, sgl_tipo_comissao, des_dispositivo_regimental, ind_excluido) - values ({}, "DESCONHECIDO", "P", "DESC", NULL, 0) - ON DUPLICATE KEY UPDATE ind_excluido = 0; - ''' - -SQLS_CRIACAO = [ - ('tipo_proposicao', ''' - insert into tipo_materia_legislativa ( - tip_materia, sgl_tipo_materia, des_tipo_materia, ind_num_automatica, - quorum_minimo_votacao, ind_excluido) - values (0, "DESC", "DESCONHECIDO", 0, 0, 0); - - insert into tipo_proposicao ( - tip_proposicao, des_tipo_proposicao, ind_mat_ou_doc, tip_mat_ou_doc, - nom_modelo, ind_excluido) - values ({}, "DESCONHECIDO", "M", 0, "DESCONHECIDO", 0); - ''', ['tipo_materia_legislativa', 0] - ), - ('tipo_resultado_votacao', ''' - insert into tipo_resultado_votacao ( - tip_resultado_votacao, nom_resultado, ind_excluido) - values ({}, "DESCONHECIDO", 0); - '''), - ('tipo_autor', SQL_INSERT_TIPO_AUTOR), - ('unidade_tramitacao', ''' - insert into unidade_tramitacao ( - cod_unid_tramitacao, cod_comissao, cod_orgao, cod_parlamentar, ind_excluido) - values ({}, NULL, NULL, 0, 0); - '''), - ('autor', SQL_INSERT_TIPO_AUTOR.format(0) + ''' - insert into autor ( - cod_autor, cod_partido, cod_comissao, cod_parlamentar, tip_autor, - nom_autor, des_cargo, col_username, ind_excluido) - values ({}, 0, 0, 0, 0, "DESCONHECIDO", "DESCONHECIDO", NULL, 0); - '''), - ('tipo_documento', ''' - insert into tipo_documento (tip_documento, des_tipo_documento, ind_excluido) - values ({}, "DESCONHECIDO", 0); - '''), - ('partido', ''' - insert into partido (cod_partido, sgl_partido, nom_partido, dat_criacao, dat_extincao, ind_excluido) - values ({}, "DESC", "DESCONHECIDO", NULL, NULL, 0); - '''), - ('legislatura', ''' - insert into legislatura (num_legislatura, dat_inicio, dat_fim, dat_eleicao, ind_excluido) - values ({}, "1/1/1", "1/1/1", "1/1/1", 0); - '''), - ('cargo_mesa', ''' - insert into cargo_mesa (cod_cargo, des_cargo, ind_unico, ind_excluido) - values ({}, "DESCONHECIDO", 0, 0); - '''), - ('orgao', ''' - insert into orgao (cod_orgao, nom_orgao, sgl_orgao, ind_unid_deliberativa, end_orgao, num_tel_orgao, ind_excluido) - values ({}, "DESCONHECIDO", "DESC", 0, NULL, NULL, 0); - '''), - ('origem', ''' - insert into origem (cod_origem, sgl_origem, nom_origem, ind_excluido) - values ({}, "DESC", "DESCONHECIDO", 0); - '''), - ('tipo_comissao', SQL_INSERT_TIPO_COMISSAO), - ('comissao', SQL_INSERT_TIPO_COMISSAO.format(0) + ''' - insert into comissao (cod_comissao, tip_comissao, nom_comissao, sgl_comissao, dat_criacao, - ind_unid_deliberativa, ind_excluido) - values ({}, 0, "DESCONHECIDO", "DESC", "1-1-1", 0, 0); - '''), - ('parlamentar', ''' - insert into parlamentar (cod_parlamentar, nom_completo, nom_parlamentar, sex_parlamentar, cod_casa, ind_ativo, ind_unid_deliberativa, ind_excluido) - values ({}, "DESCONHECIDO", "DESCONHECIDO", "M", 0, 0, 0, 0); - '''), - ('tipo_sessao_plenaria', ''' - insert into tipo_sessao_plenaria (tip_sessao, nom_sessao, ind_excluido, num_minimo) values ({}, "DESCONHECIDO", 0, 0); - '''), -] -SQLS_CRIACAO = {k: (dedent(sql.strip()), extras) - for k, sql, *extras in SQLS_CRIACAO} - - -def criar_sessao_legislativa(campo, valor): - assert campo == 'cod_sessao_leg' - [(num_legislatura,)] = exec_legado( - 'select min(num_legislatura) from legislatura where ind_excluido <> 1') - return ''' -insert into sessao_legislativa ( - cod_sessao_leg, num_legislatura, num_sessao_leg, tip_sessao_leg, - dat_inicio, dat_fim, dat_inicio_intervalo, dat_fim_intervalo, -ind_excluido) values ({}, {}, 0, "O", - "1900-01-01", "1900-01-02", "1900-01-01", "1900-01-02", 0); - '''.format(valor, num_legislatura) - - -def get_link(tabela_alvo, valor, slug): - url_base = get_url(slug) - return 'http://{}{}/{}'.format(url_base, urls[tabela_alvo], valor) - - -def get_sql_desexcluir(tabela_alvo, campo, valor, slug): - sql = 'update {} set ind_excluido = 0 where {} = {};'.format( - tabela_alvo, campo, valor) - return sql, [get_link(tabela_alvo, valor, slug)] - - -def get_sql_criar(tabela_alvo, campo, valor, slug): - if tabela_alvo == 'sessao_legislativa': - sql = criar_sessao_legislativa(campo, valor) - extras = [] - else: - sql, extras = SQLS_CRIACAO[tabela_alvo] - sql = sql.format(valor) - links = [get_link(tabela_alvo, valor, slug)] - for tabela_extra, valor_extra in extras: - links.insert(0, get_link(tabela_extra, valor_extra, slug)) - return sql, links - - -TEMPLATE_RESSUSCITADOS = '''{} -/* RESSUSCITADOS - - -SOBRE REGISTROS QUE ESTAVAM APAGADOS E FORAM RESTAURADOS - -Os registros que listamos a seguir estavam excluídos (ou simplesmente não existiam) no sistema antigo e precisaram ser restaurados (ou criados) para completarmos a migração. Foi necessário fazer isso pois outros registros ativos no sistema apontam para eles. -Vocês agora podem decidir mantê-los, ajustá-los ou excluí-los. Segue a lista: - -{} - -Se a opção for por excluir um desses registros novamente, note que só será possível fazer isso quando nada mais no sistema fizer referência a ele. - -Ao tentar excluir um registro usado em outras partes do sistema, você verá uma lista dos itens que apontam para ele de alguma forma. Para conseguir excluir você deve editar cada dos dos itens dependentes lista mostrada, retirando ou trocando a referência ao que deseja excluir. - -*/ - -{} -''' - - -def get_url(slug): - return 'sapl.{}.leg.br'.format(slug.replace('-', '.')) - - -def sem_repeticoes_mantendo_ordem(sequencia): - return OrderedDict.fromkeys(sequencia).keys() - - -def get_sqls_desexcluir_criar(preambulo, desexcluir, criar, slug): - sqls_links = [get_sql(*(args + (slug,))) - for itens, get_sql in ((desexcluir, get_sql_desexcluir), - (criar, get_sql_criar)) - for args in itens] - if not sqls_links: - return '' - else: - sqls, links = zip(*sqls_links) - - sqls = [dedent(s.strip()) + ';' - for sql in sqls - for s in sql.split(';') if s.strip()] - sqls = sem_repeticoes_mantendo_ordem(sqls) - - links = (l for ll in links for l in ll) # flatten - links = sem_repeticoes_mantendo_ordem(links) - - sqls, links = ['\n'.join(sorted(s)) for s in [sqls, links]] - return TEMPLATE_RESSUSCITADOS.format(preambulo, links, sqls) - - -def get_ressuscitar(slug): - preambulo, desexcluir, criar = get_dependencias_a_ressuscitar(slug) - return get_sqls_desexcluir_criar(preambulo, desexcluir, criar, slug) - - -def get_slug(): - arq = DIR_DADOS_MIGRACAO.child('siglas_para_slugs.yaml') - with open(arq, 'r') as arq: - siglas_para_slugs = yaml.load(arq, yaml.Loader) - sigla = NOME_BANCO_LEGADO[-3:] - return siglas_para_slugs[sigla] - - -def adiciona_ressuscitar(): - sqls = get_ressuscitar(get_slug()) - if sqls.strip(): - arq_ajustes_pre_migracao = get_arquivo_ajustes_pre_migracao() - conteudo = arq_ajustes_pre_migracao.read_file() - arq_ajustes_pre_migracao.write_file('{}\n{}'.format(conteudo, sqls)) diff --git a/sapl/legacy/scripts/shell_para_migracao.sh b/sapl/legacy/scripts/shell_para_migracao.sh deleted file mode 100755 index e7272d7ea..000000000 --- a/sapl/legacy/scripts/shell_para_migracao.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -# Inicia um shell_plus com as configurações de migração usando um banco específico -# Uso: ./shell_para_migracao.sh - -# Rode esse script a partir da raiz do projeto - -DATABASE_NAME=$1 ./manage.py shell_plus --settings sapl.legacy_migration_settings diff --git a/sapl/legacy/scripts/utils.py b/sapl/legacy/scripts/utils.py deleted file mode 100644 index 0cf623be5..000000000 --- a/sapl/legacy/scripts/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -import inspect - -from sapl.base.models import Autor -from sapl.legacy.migracao_dados import appconfs - - -def get_models_com_referencia_a(apontado): - - def tem_referencia_a_apontado(model): - return any(getattr(field, 'related_model', None) == apontado - for field in model._meta.get_fields()) - - return [model for app in appconfs for model in app.models.values() - if tem_referencia_a_apontado(model)] diff --git a/sapl/legacy/test_migracao_dados.py b/sapl/legacy/test_migracao_dados.py deleted file mode 100644 index 061264165..000000000 --- a/sapl/legacy/test_migracao_dados.py +++ /dev/null @@ -1,62 +0,0 @@ -from random import shuffle - -from .migracao_dados import (_formatar_lista_para_sql, - get_autorias_sem_repeticoes, - get_reapontamento_de_autores_repetidos) - - -def test_unifica_autores_repetidos_no_legado(): - - # cod_parlamentar, cod_autor - autores = [[0, 0], - [1, 10], - [1, 11], - [1, 12], - [2, 20], - [2, 21], - [2, 22], - [3, 30], - [3, 31], - [4, 40], - [5, 50]] - reapontamento, apagar = get_reapontamento_de_autores_repetidos(autores) - assert reapontamento == {10: 10, 11: 10, 12: 10, - 20: 20, 21: 20, 22: 20, - 30: 30, 31: 30} - assert sorted(apagar) == [11, 12, 21, 22, 31] - - # cod_autor, cod_materia, ind_primeiro_autor - autoria = [[10, 111, 0], # não é repetida, mas envolve um autor repetido - - [22, 222, 1], # não é repetida, mas envolve um autor repetido - - [10, 777, 1], # repetição c ind_primeiro_autor==1 no INÍCIO - [10, 777, 0], - [11, 777, 0], - [12, 777, 0], - - [30, 888, 0], # repetição c ind_primeiro_autor==1 no MEIO - [31, 888, 1], - [30, 888, 0], - - [11, 999, 0], # repetição SEM ind_primeiro_autor==1 - [12, 999, 0], - - [21, 999, 0], # repetição SEM ind_primeiro_autor==1 - [22, 999, 0], - ] - shuffle(autoria) # não devemos supor ordem na autoria - nova_autoria = get_autorias_sem_repeticoes(autoria, reapontamento) - assert nova_autoria == sorted([(10, 111, 0), - (20, 222, 1), - (10, 777, 1), - (30, 888, 1), - (10, 999, 0), - (20, 999, 0), - ]) - - -def test_formatar_lista_para_sql(): - assert _formatar_lista_para_sql([1, 2, 3]) == '(1, 2, 3)' - assert _formatar_lista_para_sql([1]) == '(1)' - assert _formatar_lista_para_sql([]) is None diff --git a/sapl/legacy/test_renames.py b/sapl/legacy/test_renames.py deleted file mode 100644 index 9a5c4ebaf..000000000 --- a/sapl/legacy/test_renames.py +++ /dev/null @@ -1,113 +0,0 @@ - -from django.contrib.contenttypes.fields import GenericForeignKey - -from sapl.base.models import AppConfig, Autor, CasaLegislativa, TipoAutor -from sapl.comissoes.models import \ - DocumentoAcessorio as DocumentoAcessorioComissoes -from sapl.comissoes.models import Comissao, Composicao, Participacao, Reuniao -from sapl.legacy.migracao_dados import appconfs, get_renames, legacy_app -from sapl.materia.models import (AcompanhamentoMateria, DocumentoAcessorio, - MateriaLegislativa, Proposicao, - TipoMateriaLegislativa, TipoProposicao, - Tramitacao) -from sapl.norma.models import (AnexoNormaJuridica, NormaJuridica, - NormaRelacionada, TipoVinculoNormaJuridica) -from sapl.parlamentares.models import (Frente, Mandato, Parlamentar, Partido, - TipoAfastamento, Votante, Bloco) -from sapl.protocoloadm.models import DocumentoAdministrativo -from sapl.sessao.models import (Bancada, CargoBancada, - ExpedienteMateria, Orador, OradorExpediente, - OrdemDia, RegistroVotacao, ResumoOrdenacao, - SessaoPlenaria, TipoResultadoVotacao, - VotoParlamentar) - -RENAMING_IGNORED_MODELS = [ - Votante, Frente, Bancada, Bloco, Votante, # parlamentares - Composicao, Reuniao, DocumentoAcessorioComissoes, # commissoes - AppConfig, CasaLegislativa, # base - CargoBancada, ResumoOrdenacao, # sessao - AnexoNormaJuridica, TipoVinculoNormaJuridica, # norma - -] - -RENAMING_IGNORED_FIELDS = [ - (TipoAfastamento, {'indicador'}), - (Participacao, {'composicao'}), - (Proposicao, { - 'ano', 'content_type', 'object_id', 'conteudo_gerado_related', - 'status', 'hash_code', 'texto_original'}), - (TipoProposicao, { - 'object_id', 'content_type', 'tipo_conteudo_related', 'perfis', - # não estou entendendo como esses campos são enumerados, - # mas eles não fazem parte da migração - # 'tipomaterialegislativa_set', 'tipodocumento_set', - }), - - (Tramitacao, {'ultima'}), - (SessaoPlenaria, {'finalizada', 'iniciada', 'painel_aberto', 'interativa', - 'upload_ata', - 'upload_anexo', - 'upload_pauta'}), - (ExpedienteMateria, {'votacao_aberta', 'registro_aberto'}), - (OrdemDia, {'votacao_aberta', 'registro_aberto'}), - (NormaJuridica, {'texto_integral', 'data_ultima_atualizacao', 'assuntos'}), - (Parlamentar, { - 'uf_residencia', 'municipio_residencia', 'cropping', 'fotografia'}), - (Partido, {'logo_partido', 'observacao'}), - (MateriaLegislativa, { - 'autores', 'anexadas', 'data_ultima_atualizacao', 'texto_original'}), - (DocumentoAdministrativo, { - 'protocolo', 'numero_externo', 'texto_integral'}), - (Mandato, {'titular', 'data_fim_mandato', 'data_inicio_mandato'}), - (TipoMateriaLegislativa, {'sequencia_numeracao'}), - (TipoAutor, {'content_type'}), - (TipoResultadoVotacao, {'natureza'}), - (RegistroVotacao, {'ordem', 'expediente'}), - (DocumentoAcessorio, {'arquivo', 'data_ultima_atualizacao'}), - (OradorExpediente, {'upload_anexo', 'observacao'}), - (Orador, {'upload_anexo', 'observacao'}), - (VotoParlamentar, {'user', 'ip', 'expediente', 'data_hora', 'ordem'}), - (NormaRelacionada, {'tipo_vinculo'}), - (AcompanhamentoMateria, {'confirmado', 'data_cadastro', 'usuario'}), - (Autor, {'user', 'content_type', 'object_id', 'autor_related'}), - (Comissao, {'ativa'}), - (Reuniao, {'url_audio', 'url_video', 'local_reuniao', 'upload_anexo', - 'periodo', 'upload_pauta', 'tema', 'hora_fim', 'upload_ata', - 'nome', 'hora_inicio'}) -] - - -def test_get_renames(): - field_renames, model_renames = get_renames() - all_models = {m for ac in appconfs for m in ac.get_models()} - for model in all_models: - field_names = {f.name for f in model._meta.get_fields() - if f.name != 'id' - and (f.concrete or isinstance(f, GenericForeignKey))} - if model not in field_renames: - # check ignored models in renaming - assert model in RENAMING_IGNORED_MODELS - else: - renamed = set(field_renames[model].keys()) - - match_msg_template = 'All %s field names mentioned in renames ' \ - 'must match a %s field' - - # all renamed field references correspond to a current field - assert renamed <= field_names, \ - match_msg_template % ('new', 'current') - - # ignored fields are explicitly listed - missing = field_names - renamed - if missing: - assert (model, missing) in RENAMING_IGNORED_FIELDS, \ - 'Campos faltando na renomeação,' \ - 'mas não listados explicitamente: ({}, {})'.format( - model.__name__, missing) - - # all old names correspond to a legacy field - legacy_model = legacy_app.get_model( - model_renames.get(model, model.__name__)) - legacy_field_names = {f.name for f in legacy_model._meta.fields} - assert set(field_renames[model].values()) <= legacy_field_names, \ - match_msg_template % ('old', 'legacy') diff --git a/sapl/legacy/timezonesbrasil.py b/sapl/legacy/timezonesbrasil.py deleted file mode 100644 index a9989f87d..000000000 --- a/sapl/legacy/timezonesbrasil.py +++ /dev/null @@ -1,206 +0,0 @@ -import unicodedata - -from pytz import timezone - -UF_PARA_TIMEZONE = ''' - AC America/Rio_Branco - AL America/Maceio - AP America/Belem - AM America/Manaus - BA America/Bahia - CE America/Fortaleza - DF America/Sao_Paulo - ES America/Sao_Paulo - GO America/Sao_Paulo - MA America/Fortaleza - MT America/Cuiaba - MS America/Campo_Grande - MG America/Sao_Paulo - PR America/Sao_Paulo - PB America/Fortaleza - PA America/Belem - PE America/Recife - PI America/Fortaleza - RJ America/Sao_Paulo - RN America/Fortaleza - RS America/Sao_Paulo - RO America/Porto_Velho - RR America/Boa_Vista - SC America/Sao_Paulo - SE America/Maceio - SP America/Sao_Paulo - TO America/Araguaina -''' -UF_PARA_TIMEZONE = dict(line.split() - for line in UF_PARA_TIMEZONE.strip().splitlines()) - - -def normalizar_texto(texto): - # baseado em https://gist.github.com/j4mie/557354 - norm = unicodedata.normalize('NFKD', texto.lower()) - return norm.encode('ASCII', 'ignore').decode('ascii') - -# Exceções (Anazonas e Pará): -# leste do Amazonas: America/Manaus -# oeste do Amazonas: America/Eirunepe -# leste do Pará: America/Belem -# oeste do Pará: America/Santarem -# fontes: -# https://en.wikipedia.org/wiki/Time_in_Brazil -# https://www.zeitverschiebung.net/en/timezone/america--belem -# https://www.zeitverschiebung.net/en/timezone/america--santarem -# https://www.zeitverschiebung.net/en/timezone/america--manaus -# https://www.zeitverschiebung.net/en/timezone/america--eirunepe - - -TZ_CIDADES_AMAZONAS_E_PARA = [ - ('America/Manaus', ''' - Manaus - Itacoatiara - Parintins - Manacapuru - Coari - Tefé - Humaitá - Tabatinga - Rio Preto da Eva - Maués - Carauari - Fonte Boa - São Gabriel da Cachoeira - Boca do Acre - Manicoré - Nova Olinda do Norte - Borba - São Paulo de Olivença - Barreirinha - Codajás - Iranduba - Novo Aripuanã - Urucurituba - Manaquiri - Guajará - Autazes - Santo Antônio do Içá - Urucará - Anori - Pauini - Barcelos - Careiro da Várzea - Canutama - Jutaí - Alvarães -'''), - ('America/Eirunepe', ''' - Eirunepé - Benjamin Constant - Envira -'''), - ('America/Belem', ''' - Belém - Ananindeua - Macapá - Marabá - Castanhal - Santana - Abaetetuba - Tucuruí - Paragominas - Bragança - Benevides - Capanema - Breves - Cametá - Salinópolis - Tomé Açu - Capitão Poço - Barcarena - Vigia - São Miguel do Guamá - Conceição do Araguaia - Igarapé Miri - Igarapé Açu - Moju - Portel - Itupiranga - Viseu - Soure - Mocajuba - São Félix do Xingu - Augusto Corrêa - Tucumã - Santa Maria do Pará - Acará - Maracanã - Baião - Curuçá - Marapanim - Oeiras do Pará - São João de Pirabas - Santo Antônio do Tauá - São Caetano de Odivelas - Ourém - Muaná - Afuá - Mazagão - Gurupá - Bujaru - Senador José Porfírio - Irituia - parauapebas - brejo grande do araguaia - santana do araguaia - ourilandia do norte - marituba - canaa dos carajas - goianesia do para -'''), - ('America/Santarem', ''' - Santarém - Altamira - Itaituba - Oriximiná - Alenquer - Ábidos - Monte Alegre - Almeirim - Terra Santa - Juruti - Porto de Moz - Nhamundá - Prainha - medicilandia -'''), -] -TZ_CIDADES_AMAZONAS_E_PARA = {normalizar_texto(cidade.strip()): tz - for tz, linhas in TZ_CIDADES_AMAZONAS_E_PARA - for cidade in linhas.strip().splitlines()} - - -def get_nome_timezone(cidade, uf): - uf = uf.upper() - tz = UF_PARA_TIMEZONE[uf] - if uf in ['PA', 'AM']: - cidade = normalizar_texto(cidade) - return TZ_CIDADES_AMAZONAS_E_PARA[cidade] - else: - return tz - - -def get_timezone(cidade, uf): - return timezone(get_nome_timezone(cidade, uf)) - - -def test_get_nome_timezone(): - for cidade, uf, tz in [ - ('Fortaleza', 'CE', 'America/Fortaleza'), - ('Salvador', 'BA', 'America/Bahia'), - ('Belem', 'PA', 'America/Belem'), # sem acento - ('Belém', 'PA', 'America/Belem'), # com acento - ('Santarem', 'PA', 'America/Santarem'), # sem acento - ('Santarém', 'PA', 'America/Santarem'), # com acento - ('Manaus', 'AM', 'America/Manaus'), - ('Eirunepe', 'AM', 'America/Eirunepe'), # sem acento - ('Eirunepé', 'AM', 'America/Eirunepe'), # com acento - ]: - assert get_nome_timezone(cidade, uf) == tz, (cidade, uf, tz) diff --git a/sapl/legacy/views.py b/sapl/legacy/views.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/sapl/legacy_migration_settings.py b/sapl/legacy_migration_settings.py deleted file mode 100644 index 463fbb7a6..000000000 --- a/sapl/legacy_migration_settings.py +++ /dev/null @@ -1,64 +0,0 @@ -import os -import re - -import pytz -import yaml -from decouple import Config, RepositoryEnv -from dj_database_url import parse as db_url - -from sapl.legacy.scripts.exporta_zope.variaveis_comuns import \ - DIR_DADOS_MIGRACAO -from sapl.legacy.timezonesbrasil import get_timezone - -from .settings import * # flake8: noqa - -config = Config(RepositoryEnv(BASE_DIR.child('legacy', '.env'))) - - -INSTALLED_APPS += ( - 'sapl.legacy', # legacy reversed model definitions -) - -DATABASES['legacy'] = config('DATABASE_URL_FONTE', cast=db_url,) -DATABASES['default'] = config( - 'DATABASE_URL_DESTINO', - cast=lambda v: v if isinstance(v, dict) else db_url(v), - default=DATABASES['default']) - -# Sobrescreve o nome dos bancos caso a variável de ambiente seja definida -# Útil para migração em lote de vários bancos -DATABASE_NAME_OVERRIDE = os.environ.get('DATABASE_NAME') -if DATABASE_NAME_OVERRIDE: - DATABASES['legacy']['NAME'] = DATABASE_NAME_OVERRIDE - # não altera o nome se o destino é um banco em memória - if not DATABASES['default']['NAME'] == ':memory:': - DATABASES['default']['NAME'] = DATABASE_NAME_OVERRIDE - -DATABASE_ROUTERS = ['sapl.legacy.router.LegacyRouter', ] - -DEBUG = True - -# delisga indexação fulltext em tempo real -HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.BaseSignalProcessor' - -SHELL_PLUS_DONT_LOAD = ['legacy'] - -NOME_BANCO_LEGADO = DATABASES['legacy']['NAME'] -DIR_REPO = Path(DIR_DADOS_MIGRACAO, 'repos', NOME_BANCO_LEGADO) - -MEDIA_ROOT = DIR_REPO - - -# configura timezone de migração -match = re.match('sapl_cm_(.*)', NOME_BANCO_LEGADO) -SIGLA_CASA = match.group(1) -_PATH_TABELA_TIMEZONES = DIR_DADOS_MIGRACAO.child('tabela_timezones.yaml') -with open(_PATH_TABELA_TIMEZONES, 'r') as arq: - tabela_timezones = yaml.load(arq, yaml.Loader) -municipio, uf, nome_timezone = tabela_timezones[SIGLA_CASA] -if nome_timezone: - PYTZ_TIMEZONE = pytz.timezone(nome_timezone) -else: - PYTZ_TIMEZONE = get_timezone(municipio, uf) - -TIME_ZONE = PYTZ_TIMEZONE.zone diff --git a/sapl/lexml/legacy.yaml b/sapl/lexml/legacy.yaml deleted file mode 100644 index 12414248e..000000000 --- a/sapl/lexml/legacy.yaml +++ /dev/null @@ -1,18 +0,0 @@ -LexmlProvedor (LexmlRegistroProvedor): - email_responsavel: adm_email - id_provedor: id_provedor - id_responsavel: id_responsavel - nome: nom_provedor - nome_responsavel: nom_responsavel - sigla: sgl_provedor - tipo: tipo - xml: xml_provedor - -LexmlPublicador (LexmlRegistroPublicador): - email_responsavel: adm_email - id_publicador: id_publicador - id_responsavel: id_responsavel - nome: nom_publicador - nome_responsavel: nom_responsavel - sigla: sigla - tipo: tipo diff --git a/sapl/lexml/models.py b/sapl/lexml/models.py index bec1b52ec..1a5d27144 100644 --- a/sapl/lexml/models.py +++ b/sapl/lexml/models.py @@ -1,9 +1,7 @@ -import reversion from django.db import models from django.utils.translation import ugettext_lazy as _ -@reversion.register() class LexmlProvedor(models.Model): # LexmlRegistroProvedor id_provedor = models.PositiveIntegerField(verbose_name=_('Id do provedor')) nome = models.CharField(max_length=255, verbose_name=_('Nome do provedor')) @@ -38,7 +36,6 @@ class LexmlProvedor(models.Model): # LexmlRegistroProvedor return self.nome -@reversion.register() class LexmlPublicador(models.Model): id_publicador = models.PositiveIntegerField( verbose_name=_('Id do publicador')) diff --git a/sapl/materia/legacy.yaml b/sapl/materia/legacy.yaml deleted file mode 100644 index 9ff81287f..000000000 --- a/sapl/materia/legacy.yaml +++ /dev/null @@ -1,146 +0,0 @@ -TipoMateriaLegislativa: - descricao: des_tipo_materia - num_automatica: ind_num_automatica - quorum_minimo_votacao: quorum_minimo_votacao - sigla: sgl_tipo_materia - -RegimeTramitacao: - descricao: des_regime_tramitacao - -Origem: - nome: nom_origem - sigla: sgl_origem - -MateriaLegislativa: - ano: ano_ident_basica - ano_origem_externa: ano_origem_externa - apelido: nom_apelido - complementar: ind_complementar - data_apresentacao: dat_apresentacao - data_fim_prazo: dat_fim_prazo - data_origem_externa: dat_origem_externa - data_publicacao: dat_publicacao - dias_prazo: num_dias_prazo - em_tramitacao: ind_tramitacao - ementa: txt_ementa - indexacao: txt_indexacao - local_origem_externa: cod_local_origem_externa - numero: num_ident_basica - numero_origem_externa: num_origem_externa - numero_protocolo: num_protocolo - objeto: des_objeto - observacao: txt_observacao - polemica: ind_polemica - regime_tramitacao: cod_regime_tramitacao - resultado: txt_resultado - tipo_apresentacao: tip_apresentacao - tipo: tip_id_basica - tipo_origem_externa: tip_origem_externa - -Autoria: - autor: cod_autor - materia: cod_materia - primeiro_autor: ind_primeiro_autor - -AcompanhamentoMateria (AcompMateria): - email: end_email - hash: txt_hash - materia: cod_materia - -Anexada: - data_anexacao: dat_anexacao - data_desanexacao: dat_desanexacao - materia_anexada: cod_materia_anexada - materia_principal: cod_materia_principal - -AssuntoMateria: - assunto: des_assunto - dispositivo: des_dispositivo - -DespachoInicial: - materia: cod_materia - comissao: cod_comissao - -TipoDocumento: - descricao: des_tipo_documento - -DocumentoAcessorio: - autor: nom_autor_documento - data: dat_documento - ementa: txt_ementa - indexacao: txt_indexacao - materia: cod_materia - nome: nom_documento - tipo: tip_documento - -MateriaAssunto: - assunto: cod_assunto - materia: cod_materia - -Numeracao: - ano_materia: ano_materia - data_materia: dat_materia - materia: cod_materia - numero_materia: num_materia - tipo_materia: tip_materia - -Orgao: - endereco: end_orgao - nome: nom_orgao - sigla: sgl_orgao - telefone: num_tel_orgao - unidade_deliberativa: ind_unid_deliberativa - -TipoFimRelatoria: - descricao: des_fim_relatoria - -Relatoria: - comissao: cod_comissao - data_designacao_relator: dat_desig_relator - data_destituicao_relator: dat_destit_relator - materia: cod_materia - parlamentar: cod_parlamentar - tipo_fim_relatoria: tip_fim_relatoria - -Parecer: - materia: cod_materia - parecer: txt_parecer - relatoria: cod_relatoria - tipo_apresentacao: tip_apresentacao - tipo_conclusao: tip_conclusao - -TipoProposicao: - descricao: des_tipo_proposicao - -Proposicao: - autor: cod_autor - data_devolucao: dat_devolucao - data_envio: dat_envio - data_recebimento: dat_recebimento - descricao: txt_descricao - justificativa_devolucao: txt_justif_devolucao - materia_de_vinculo: cod_materia - numero_proposicao: num_proposicao - tipo: tip_proposicao - -StatusTramitacao: - descricao: des_status - indicador: ind_fim_tramitacao - sigla: sgl_status - -UnidadeTramitacao: - comissao: cod_comissao - orgao: cod_orgao - parlamentar: cod_parlamentar - -Tramitacao: - data_encaminhamento: dat_encaminha - data_fim_prazo: dat_fim_prazo - data_tramitacao: dat_tramitacao - materia: cod_materia - status: cod_status - texto: txt_tramitacao - turno: sgl_turno - unidade_tramitacao_destino: cod_unid_tram_dest - unidade_tramitacao_local: cod_unid_tram_local - urgente: ind_urgencia diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 1ff9268e9..426b02168 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -8,7 +8,6 @@ from django.template import defaultfilters from django.utils import formats, timezone from django.utils.translation import ugettext_lazy as _ from model_utils import Choices -import reversion from sapl.base.models import SEQUENCIA_NUMERACAO_PROTOCOLO, Autor from sapl.comissoes.models import Comissao, Reuniao @@ -34,7 +33,6 @@ def grupo_autor(): return grupo.id -@reversion.register() class TipoProposicao(models.Model): descricao = models.CharField( max_length=50, @@ -108,7 +106,6 @@ class TipoMateriaManager(models.Manager): ) -@reversion.register() class TipoMateriaLegislativa(models.Model): objects = TipoMateriaManager() sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) @@ -148,7 +145,6 @@ class TipoMateriaLegislativa(models.Model): return self.descricao -@reversion.register() class RegimeTramitacao(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -161,7 +157,6 @@ class RegimeTramitacao(models.Model): return self.descricao -@reversion.register() class Origem(models.Model): sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) @@ -187,7 +182,6 @@ def anexo_upload_path(instance, filename): return texto_upload_path(instance, filename, subpath=instance.materia.ano) -@reversion.register() class MateriaLegislativa(models.Model): tipo = models.ForeignKey( @@ -384,7 +378,6 @@ class MateriaLegislativa(models.Model): update_fields=update_fields) -@reversion.register() class Autoria(models.Model): autor = models.ForeignKey(Autor, verbose_name=_('Autor'), @@ -407,7 +400,6 @@ class Autoria(models.Model): 'autor': self.autor, 'materia': self.materia} -@reversion.register() class AcompanhamentoMateria(models.Model): usuario = models.CharField(max_length=50) materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) @@ -436,7 +428,6 @@ class AcompanhamentoMateria(models.Model): } -@reversion.register() class PautaReuniao(models.Model): reuniao = models.ForeignKey( Reuniao, related_name='reuniao_set', @@ -462,7 +453,6 @@ class PautaReuniao(models.Model): } -@reversion.register() class Anexada(models.Model): materia_principal = models.ForeignKey( MateriaLegislativa, related_name='materia_principal_set', @@ -488,7 +478,6 @@ class Anexada(models.Model): 'materia_anexada': self.materia_anexada} -@reversion.register() class AssuntoMateria(models.Model): assunto = models.CharField( max_length=50, @@ -507,7 +496,6 @@ class AssuntoMateria(models.Model): return self.assunto -@reversion.register() class DespachoInicial(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) comissao = models.ForeignKey( @@ -524,7 +512,6 @@ class DespachoInicial(models.Model): 'comissao': self.comissao} -@reversion.register() class TipoDocumento(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Tipo Documento')) @@ -545,7 +532,6 @@ class TipoDocumento(models.Model): return self.descricao -@reversion.register() class DocumentoAcessorio(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) tipo = models.ForeignKey( @@ -613,7 +599,6 @@ class DocumentoAcessorio(models.Model): update_fields=update_fields) -@reversion.register() class MateriaAssunto(models.Model): # TODO M2M ?? assunto = models.ForeignKey( @@ -635,7 +620,6 @@ class MateriaAssunto(models.Model): 'materia': self.materia, 'assunto': self.assunto} -@reversion.register() class Numeracao(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) tipo_materia = models.ForeignKey( @@ -663,7 +647,6 @@ class Numeracao(models.Model): 'ano': self.ano_materia} -@reversion.register() class Orgao(models.Model): nome = models.CharField(max_length=256, verbose_name=_('Nome')) sigla = models.CharField(max_length=15, verbose_name=_('Sigla')) @@ -693,7 +676,6 @@ class Orgao(models.Model): '%(nome)s - %(sigla)s') % {'nome': self.nome, 'sigla': self.sigla} -@reversion.register() class TipoFimRelatoria(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Tipo Fim Relatoria')) @@ -707,7 +689,6 @@ class TipoFimRelatoria(models.Model): return self.descricao -@reversion.register() class Relatoria(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) parlamentar = models.ForeignKey(Parlamentar, @@ -744,7 +725,6 @@ class Relatoria(models.Model): 'data': self.data_designacao_relator.strftime("%d/%m/%Y")} -@reversion.register() class Parecer(models.Model): relatoria = models.ForeignKey(Relatoria, on_delete=models.CASCADE) materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) @@ -764,7 +744,6 @@ class Parecer(models.Model): } -@reversion.register() class Proposicao(models.Model): autor = models.ForeignKey( Autor, @@ -1074,7 +1053,6 @@ class HistoricoProposicao(models.Model): return f'{self.data_hora} - {self.STATUS_PROPOSICAO[self.status]} - {str(self.proposicao)}' -@reversion.register() class StatusTramitacao(models.Model): INDICADOR_CHOICES = Choices(('F', 'fim', _('Fim')), ('R', 'retorno', _('Retorno'))) @@ -1110,7 +1088,6 @@ class UnidadeTramitacaoManager(models.Manager): ).order_by('nome_composto') -@reversion.register() class UnidadeTramitacao(models.Model): comissao = models.ForeignKey( Comissao, blank=True, null=True, @@ -1156,7 +1133,6 @@ class UnidadeTramitacao(models.Model): return _('%(parlamentar)s') % {'parlamentar': self.parlamentar} -@reversion.register() class Tramitacao(models.Model): TURNO_CHOICES = Choices( ('P', 'primeiro', _('Primeiro')), diff --git a/sapl/norma/legacy.yaml b/sapl/norma/legacy.yaml deleted file mode 100644 index 23bf5bb80..000000000 --- a/sapl/norma/legacy.yaml +++ /dev/null @@ -1,46 +0,0 @@ -AssuntoNorma: - assunto: des_assunto - descricao: des_estendida - -TipoNormaJuridica: - descricao: des_tipo_norma - equivalente_lexml: voc_lexml - sigla: sgl_tipo_norma - -NormaJuridica: - ano: ano_norma - complemento: ind_complemento - data: dat_norma - data_publicacao: dat_publicacao - data_vigencia: dat_vigencia - ementa: txt_ementa - esfera_federacao: tip_esfera_federacao - indexacao: txt_indexacao - materia: cod_materia - numero: num_norma - observacao: txt_observacao - pagina_fim_publicacao: num_pag_fim_publ - pagina_inicio_publicacao: num_pag_inicio_publ - timestamp: timestamp - tipo: tip_norma - veiculo_publicacao: des_veiculo_publicacao - -LegislacaoCitada: - alinea: des_alinea - artigo: des_artigo - capitulo: des_capitulo - disposicoes: des_disposicoes - inciso: des_inciso - item: des_item - livro: des_livro - materia: cod_materia - norma: cod_norma - paragrafo: des_paragrafo - parte: des_parte - secao: des_secao - subsecao: des_subsecao - titulo: des_titulo - -NormaRelacionada (VinculoNormaJuridica): - norma_principal: cod_norma_referente - norma_relacionada: cod_norma_referida diff --git a/sapl/norma/models.py b/sapl/norma/models.py index d4c258d5a..3e33d11ba 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -4,7 +4,6 @@ from django.template import defaultfilters from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from model_utils import Choices -import reversion from sapl.base.models import Autor from sapl.compilacao.models import TextoArticulado @@ -16,7 +15,6 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, OverwriteStorage) -@reversion.register() class AssuntoNorma(models.Model): assunto = models.CharField(max_length=50, verbose_name=_('Assunto')) descricao = models.CharField( @@ -31,7 +29,6 @@ class AssuntoNorma(models.Model): return self.assunto -@reversion.register() class TipoNormaJuridica(models.Model): # TODO transform into Domain Model and use an FK for the field EQUIVALENTE_LEXML_CHOICES = ((name, name) for name in @@ -126,7 +123,6 @@ class NormaJuridicaManager(models.Manager): return qs -@reversion.register() class NormaJuridica(models.Model): objects = NormaJuridicaManager() @@ -346,7 +342,6 @@ class ViewNormasEstatisticas(models.Model): db_table = "norma_viewnormasestatisticas" -@reversion.register() class AutoriaNorma(models.Model): autor = models.ForeignKey(Autor, verbose_name=_('Autor'), @@ -369,7 +364,6 @@ class AutoriaNorma(models.Model): 'autor': self.autor, 'norma': self.norma} -@reversion.register() class LegislacaoCitada(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) norma = models.ForeignKey(NormaJuridica, on_delete=models.CASCADE) @@ -407,7 +401,6 @@ class LegislacaoCitada(models.Model): return str(self.norma) -@reversion.register() class TipoVinculoNormaJuridica(models.Model): sigla = models.CharField( max_length=1, blank=True, verbose_name=_('Sigla')) @@ -428,7 +421,6 @@ class TipoVinculoNormaJuridica(models.Model): return self.descricao_ativa -@reversion.register() class NormaRelacionada(models.Model): norma_principal = models.ForeignKey( NormaJuridica, @@ -462,7 +454,6 @@ class NormaRelacionada(models.Model): 'norma_relacionada': str(self.norma_relacionada)} -@reversion.register() class AnexoNormaJuridica(models.Model): norma = models.ForeignKey( NormaJuridica, diff --git a/sapl/painel/models.py b/sapl/painel/models.py index aec696a53..8a178e6c2 100644 --- a/sapl/painel/models.py +++ b/sapl/painel/models.py @@ -1,9 +1,7 @@ -import reversion from django.db import models from django.utils.translation import ugettext_lazy as _ -@reversion.register() class Painel(models.Model): PAINEL_TYPES = ( ('C', 'Completo'), @@ -24,7 +22,6 @@ class Painel(models.Model): return str(self.aberto) + ":" + self.data_painel.strftime("%d/%m/%Y") -@reversion.register() class Cronometro(models.Model): CRONOMETRO_TYPES = ( ('A', _('Aparte')), diff --git a/sapl/parlamentares/legacy.yaml b/sapl/parlamentares/legacy.yaml deleted file mode 100644 index fc72431f5..000000000 --- a/sapl/parlamentares/legacy.yaml +++ /dev/null @@ -1,101 +0,0 @@ -Legislatura: - numero: num_legislatura - data_eleicao: dat_eleicao - data_fim: dat_fim - data_inicio: dat_inicio - -SessaoLegislativa: - data_fim: dat_fim - data_fim_intervalo: dat_fim_intervalo - data_inicio: dat_inicio - data_inicio_intervalo: dat_inicio_intervalo - legislatura: num_legislatura - numero: num_sessao_leg - tipo: tip_sessao_leg - -Coligacao: - legislatura: num_legislatura - nome: nom_coligacao - numero_votos: num_votos_coligacao - -Partido: - data_criacao: dat_criacao - data_extincao: dat_extincao - nome: nom_partido - sigla: sgl_partido - -ComposicaoColigacao: - coligacao: cod_coligacao - partido: cod_partido - -NivelInstrucao: - descricao: des_nivel_instrucao - -SituacaoMilitar: - descricao: des_tipo_situacao - -Parlamentar: - ativo: ind_ativo - biografia: txt_biografia - cep_residencia: num_cep_resid - cpf: num_cpf - data_nascimento: dat_nascimento - email: end_email - endereco_residencia: end_residencial - endereco_web: end_web - fax: num_fax_parlamentar - fax_residencia: num_fax_resid - locais_atuacao: des_local_atuacao - nivel_instrucao: cod_nivel_instrucao - nome_completo: nom_completo - nome_parlamentar: nom_parlamentar - numero_gab_parlamentar: num_gab_parlamentar - profissao: nom_profissao - rg: num_rg - sexo: sex_parlamentar - situacao_militar: tip_situacao_militar - telefone: num_tel_parlamentar - telefone_residencia: num_tel_resid - titulo_eleitor: num_tit_eleitor - -TipoDependente: - descricao: des_tipo_dependente - -Dependente: - cpf: num_cpf - data_nascimento: dat_nascimento - nome: nom_dependente - parlamentar: cod_parlamentar - rg: num_rg - sexo: sex_dependente - tipo: tip_dependente - titulo_eleitor: num_tit_eleitor - -Filiacao: - data: dat_filiacao - data_desfiliacao: dat_desfiliacao - parlamentar: cod_parlamentar - partido: cod_partido - -TipoAfastamento: - descricao: des_afastamento - dispositivo: des_dispositivo - -Mandato: - coligacao: cod_coligacao - data_expedicao_diploma: dat_expedicao_diploma - legislatura: num_legislatura - observacao: txt_observacao - parlamentar: cod_parlamentar - tipo_afastamento: tip_afastamento - tipo_causa_fim_mandato: tip_causa_fim_mandato - votos_recebidos: num_votos_recebidos - -CargoMesa: - descricao: des_cargo - unico: ind_unico - -ComposicaoMesa: - cargo: cod_cargo - parlamentar: cod_parlamentar - sessao_legislativa: cod_sessao_leg diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index fda61ef95..7595c71a9 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -5,7 +5,6 @@ from django.utils.translation import ugettext_lazy as _ from image_cropping.fields import ImageCropField, ImageRatioField from model_utils import Choices from prompt_toolkit.key_binding.bindings.named_commands import self_insert -import reversion from sapl.base.models import Autor from sapl.decorators import vigencia_atual @@ -15,7 +14,6 @@ from sapl.utils import (LISTA_DE_UFS, YES_NO_CHOICES, SaplGenericRelation, restringe_tipos_de_arquivo_img, texto_upload_path) -@reversion.register() class Legislatura(models.Model): numero = models.PositiveIntegerField(verbose_name=_('Número')) data_inicio = models.DateField(verbose_name=_('Data Início')) @@ -47,7 +45,6 @@ class Legislatura(models.Model): 'end': self.data_fim.year} -@reversion.register() class SessaoLegislativa(models.Model): TIPO_SESSAO_CHOICES = Choices( ('O', 'ordinaria', _('Ordinária')), @@ -81,7 +78,6 @@ class SessaoLegislativa(models.Model): 'fim': self.data_fim.year} -@reversion.register() class Coligacao(models.Model): legislatura = models.ForeignKey(Legislatura, on_delete=models.PROTECT, @@ -108,7 +104,6 @@ def logo_upload_path(instance, filename): return get_logo_media_path(instance, 'logo', filename) -@reversion.register() class Partido(models.Model): sigla = models.CharField(max_length=20, verbose_name=_('Sigla')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) @@ -136,7 +131,6 @@ class Partido(models.Model): } -@reversion.register() class ComposicaoColigacao(models.Model): # TODO M2M partido = models.ForeignKey(Partido, @@ -155,7 +149,6 @@ class ComposicaoColigacao(models.Model): } -@reversion.register() class NivelInstrucao(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Nível de Instrução')) @@ -169,7 +162,6 @@ class NivelInstrucao(models.Model): return self.descricao -@reversion.register() class SituacaoMilitar(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Situação Militar')) @@ -196,7 +188,6 @@ def true_false_none(x): return None -@reversion.register() class Parlamentar(models.Model): FEMININO = 'F' MASCULINO = 'M' @@ -342,7 +333,6 @@ class Parlamentar(models.Model): update_fields=update_fields) -@reversion.register() class TipoDependente(models.Model): descricao = models.CharField(max_length=150, verbose_name=_('Descrição')) @@ -355,7 +345,6 @@ class TipoDependente(models.Model): return self.descricao -@reversion.register() class Dependente(models.Model): FEMININO = 'F' MASCULINO = 'M' @@ -388,7 +377,6 @@ class Dependente(models.Model): return self.nome -@reversion.register() class Filiacao(models.Model): data = models.DateField(verbose_name=_('Data Filiação')) parlamentar = models.ForeignKey(Parlamentar, on_delete=models.CASCADE) @@ -411,7 +399,6 @@ class Filiacao(models.Model): } -@reversion.register() class TipoAfastamento(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) indicador = models.CharField( @@ -430,7 +417,6 @@ class TipoAfastamento(models.Model): return self.descricao -@reversion.register() class Mandato(models.Model): parlamentar = models.ForeignKey(Parlamentar, on_delete=models.CASCADE) tipo_afastamento = models.ForeignKey( @@ -484,7 +470,6 @@ class Mandato(models.Model): f.data_desfiliacao or timezone.datetime.max.date())] -@reversion.register() class CargoMesa(models.Model): # TODO M2M ???? descricao = models.CharField( @@ -501,7 +486,6 @@ class CargoMesa(models.Model): return self.descricao -@reversion.register() class MesaDiretora(models.Model): data_inicio = models.DateField(verbose_name=_('Data Início'), null=True) data_fim = models.DateField(verbose_name=_('Data Fim'), null=True) @@ -520,7 +504,6 @@ class MesaDiretora(models.Model): } -@reversion.register() class ComposicaoMesa(models.Model): # TODO M2M ???? Ternary????? parlamentar = models.ForeignKey(Parlamentar, on_delete=models.PROTECT) @@ -539,7 +522,6 @@ class ComposicaoMesa(models.Model): } -@reversion.register() class Frente(models.Model): ''' * Uma frente agrupa vários parlamentares @@ -581,7 +563,6 @@ class Frente(models.Model): return self.nome -@reversion.register() class FrenteCargo(models.Model): nome_cargo = models.CharField( max_length=80, @@ -600,7 +581,6 @@ class FrenteCargo(models.Model): return f"{self.nome_cargo}" -@reversion.register() class FrenteParlamentar(models.Model): frente = models.ForeignKey( Frente, @@ -652,7 +632,6 @@ class Votante(models.Model): return self.user.username -@reversion.register() class Bloco(models.Model): ''' * blocos podem existir por mais de uma legislatura @@ -694,7 +673,6 @@ class Bloco(models.Model): return self.nome -@reversion.register() class BlocoCargo(models.Model): nome_cargo = models.CharField( max_length=120, @@ -713,7 +691,6 @@ class BlocoCargo(models.Model): return f"{self.nome_cargo}" -@reversion.register() class BlocoMembro(models.Model): bloco = models.ForeignKey( Bloco, diff --git a/sapl/protocoloadm/legacy.yaml b/sapl/protocoloadm/legacy.yaml deleted file mode 100644 index 7dae79f73..000000000 --- a/sapl/protocoloadm/legacy.yaml +++ /dev/null @@ -1,62 +0,0 @@ -TipoDocumentoAdministrativo: - descricao: des_tipo_documento - sigla: sgl_tipo_documento - -DocumentoAdministrativo: - ano: ano_documento - assunto: txt_assunto - autor: cod_autor - data: dat_documento - data_fim_prazo: dat_fim_prazo - dias_prazo: num_dias_prazo - interessado: txt_interessado - numero: num_documento - observacao: txt_observacao - tipo: tip_documento - tramitacao: ind_tramitacao - -DocumentoAcessorioAdministrativo: - arquivo: nom_arquivo - assunto: txt_assunto - autor: nom_autor_documento - data: dat_documento - documento: cod_documento - indexacao: txt_indexacao - nome: nom_documento - tipo: tip_documento - -Protocolo: - ano: ano_protocolo - anulado: ind_anulado - assunto_ementa: txt_assunto_ementa - autor: cod_autor - data: dat_protocolo - hora: hor_protocolo - interessado: txt_interessado - ip_anulacao: txt_ip_anulacao - justificativa_anulacao: txt_just_anulacao - numero: num_protocolo - numero_paginas: num_paginas - observacao: txt_observacao - timestamp: dat_timestamp - timestamp_anulacao: timestamp_anulacao - tipo_documento: tip_documento - tipo_materia: tip_materia - tipo_processo: tip_processo - tipo_protocolo: tip_protocolo - user_anulacao: txt_user_anulacao - -StatusTramitacaoAdministrativo: - descricao: des_status - indicador: ind_fim_tramitacao - sigla: sgl_status - -TramitacaoAdministrativo: - data_encaminhamento: dat_encaminha - data_fim_prazo: dat_fim_prazo - data_tramitacao: dat_tramitacao - documento: cod_documento - status: cod_status - texto: txt_tramitacao - unidade_tramitacao_destino: cod_unid_tram_dest - unidade_tramitacao_local: cod_unid_tram_local diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py index b64809bf0..3cdf32735 100644 --- a/sapl/protocoloadm/models.py +++ b/sapl/protocoloadm/models.py @@ -5,7 +5,6 @@ from django.utils import timezone from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ from model_utils import Choices -import reversion from sapl.base.models import Autor, AppConfig as SaplAppConfig from sapl.materia.models import TipoMateriaLegislativa, UnidadeTramitacao,\ @@ -15,7 +14,6 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, texto_upload_path, OverwriteStorage) -@reversion.register() class TipoDocumentoAdministrativo(models.Model): sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -54,7 +52,6 @@ def texto_upload_path(instance, filename): """ -@reversion.register() class Protocolo(models.Model): numero = models.PositiveIntegerField( blank=False, @@ -157,7 +154,6 @@ class Protocolo(models.Model): } -@reversion.register() class DocumentoAdministrativo(models.Model): tipo = models.ForeignKey( TipoDocumentoAdministrativo, on_delete=models.PROTECT, @@ -345,7 +341,6 @@ class DocumentoAdministrativo(models.Model): update_fields=update_fields) -@reversion.register() class DocumentoAcessorioAdministrativo(models.Model): documento = models.ForeignKey(DocumentoAdministrativo, on_delete=models.PROTECT) @@ -403,7 +398,6 @@ class DocumentoAcessorioAdministrativo(models.Model): update_fields=update_fields) -@reversion.register() class StatusTramitacaoAdministrativo(models.Model): INDICADOR_CHOICES = Choices( ('F', 'fim', _('Fim')), @@ -427,7 +421,6 @@ class StatusTramitacaoAdministrativo(models.Model): return self.descricao -@reversion.register() class TramitacaoAdministrativo(models.Model): status = models.ForeignKey( StatusTramitacaoAdministrativo, @@ -481,7 +474,6 @@ class TramitacaoAdministrativo(models.Model): } -@reversion.register() class Anexado(models.Model): documento_principal = models.ForeignKey( DocumentoAdministrativo, related_name='documento_principal_set', @@ -512,7 +504,6 @@ class Anexado(models.Model): } -@reversion.register() class VinculoDocAdminMateria(models.Model): documento = models.ForeignKey( DocumentoAdministrativo, related_name='materialegislativa_vinculada_set', @@ -543,7 +534,6 @@ class VinculoDocAdminMateria(models.Model): return f'Vinculo: {self.documento} - {self.materia}' -@reversion.register() class AcompanhamentoDocumento(models.Model): usuario = models.CharField(max_length=50) documento = models.ForeignKey( diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index 6a3c45f4b..cdaa71516 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -9,7 +9,6 @@ from django.core import exceptions from django.db import models, router from django.db.utils import DEFAULT_DB_ALIAS from django.utils.translation import ugettext_lazy as _ -import reversion from sapl.rules import (SAPL_GROUP_ADMINISTRATIVO, SAPL_GROUP_COMISSOES, SAPL_GROUP_GERAL, SAPL_GROUP_MATERIA, SAPL_GROUP_NORMA, @@ -237,14 +236,6 @@ def cria_usuarios_padrao(): rules.cria_usuarios_padrao() -def revision_pre_delete_signal(sender, **kwargs): - with reversion.create_revision(): - kwargs['instance'].save() - reversion.set_comment("Deletado pelo sinal.") - - models.signals.post_migrate.connect(receiver=update_groups) models.signals.post_migrate.connect( receiver=create_proxy_permissions, dispatch_uid="django.contrib.auth.management.create_permissions") -models.signals.pre_delete.connect( - receiver=revision_pre_delete_signal, dispatch_uid="pre_delete_signal") diff --git a/sapl/sessao/legacy.yaml b/sapl/sessao/legacy.yaml deleted file mode 100644 index 6df4dd90d..000000000 --- a/sapl/sessao/legacy.yaml +++ /dev/null @@ -1,77 +0,0 @@ -TipoSessaoPlenaria: - nome: nom_sessao - quorum_minimo: num_minimo - -SessaoPlenaria: - cod_andamento_sessao: cod_andamento_sessao - data_fim: dat_fim_sessao - data_inicio: dat_inicio_sessao - hora_fim: hr_fim_sessao - hora_inicio: hr_inicio_sessao - legislatura: num_legislatura - numero: num_sessao_plen - sessao_legislativa: cod_sessao_leg - tipo: tip_sessao - url_audio: url_audio - url_video: url_video - -: - data_ordem: dat_ordem - materia: cod_materia - numero_ordem: num_ordem - observacao: txt_observacao - resultado: txt_resultado - sessao_plenaria: cod_sessao_plen - tipo_votacao: tip_votacao - -ExpedienteMateria: - -TipoExpediente: - nome: nom_expediente - -ExpedienteSessao (ExpedienteSessaoPlenaria): - conteudo: txt_expediente - sessao_plenaria: cod_sessao_plen - tipo: cod_expediente - -IntegranteMesa (MesaSessaoPlenaria): - cargo: cod_cargo - parlamentar: cod_parlamentar - sessao_plenaria: cod_sessao_plen - -: - numero_ordem: num_ordem - parlamentar: cod_parlamentar - sessao_plenaria: cod_sessao_plen - url_discurso: url_discurso - -Orador (Oradores): - -OradorExpediente (OradoresExpediente): - -OrdemDia: - -PresencaOrdemDia (OrdemDiaPresenca): - parlamentar: cod_parlamentar - sessao_plenaria: cod_sessao_plen - -TipoResultadoVotacao: - nome: nom_resultado - -RegistroVotacao: - materia: cod_materia - numero_abstencoes: num_abstencao - numero_votos_nao: num_votos_nao - numero_votos_sim: num_votos_sim - observacao: txt_observacao - tipo_resultado_votacao: tip_resultado_votacao - -VotoParlamentar (RegistroVotacaoParlamentar): - parlamentar: cod_parlamentar - votacao: cod_votacao - voto: vot_parlamentar - -SessaoPlenariaPresenca: - data_sessao: dat_sessao - parlamentar: cod_parlamentar - sessao_plenaria: cod_sessao_plen diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index 0a1b8e06d..55fe581a1 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -6,7 +6,6 @@ from django.db.models import Q, F from django.utils import timezone, formats from django.utils.translation import ugettext_lazy as _ from model_utils import Choices -import reversion from sapl.base.models import Autor from sapl.materia.models import MateriaLegislativa @@ -20,7 +19,6 @@ from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation, OverwriteStorage) -@reversion.register() class CargoBancada(models.Model): nome_cargo = models.CharField(max_length=80, verbose_name=_('Cargo de Bancada')) @@ -38,7 +36,6 @@ class CargoBancada(models.Model): return self.nome_cargo -@reversion.register() class Bancada(models.Model): legislatura = models.ForeignKey(Legislatura, on_delete=models.PROTECT, @@ -76,7 +73,6 @@ class Bancada(models.Model): return self.nome -@reversion.register() class TipoSessaoPlenaria(models.Model): TIPO_NUMERACAO_CHOICES = Choices( @@ -157,7 +153,6 @@ def anexo_upload_path(instance, filename): # return get_sessao_media_path(instance, 'anexo', filename) -@reversion.register() class SessaoPlenaria(models.Model): # TODO trash??? Seems to have been a FK in the past. Would be: # andamento_sessao = models.ForeignKey( @@ -359,7 +354,6 @@ class SessaoPlenaria(models.Model): ).update(data_ordem=self.data_inicio) -@reversion.register() class AbstractOrdemDia(models.Model): TIPO_VOTACAO_CHOICES = Choices( (1, 'simbolica', 'Simbólica'), @@ -413,7 +407,6 @@ class AbstractOrdemDia(models.Model): self.numero_ordem, self.materia, self.sessao_plenaria) -@reversion.register() class ExpedienteMateria(AbstractOrdemDia): class Meta: @@ -422,7 +415,6 @@ class ExpedienteMateria(AbstractOrdemDia): ordering = ['numero_ordem'] -@reversion.register() class TipoExpediente(models.Model): nome = models.CharField(max_length=100, verbose_name=_('Tipo')) ordenacao = models.PositiveIntegerField( @@ -439,7 +431,6 @@ class TipoExpediente(models.Model): return self.nome -@reversion.register() class ExpedienteSessao(models.Model): # ExpedienteSessaoPlenaria sessao_plenaria = models.ForeignKey( SessaoPlenaria, @@ -459,7 +450,6 @@ class ExpedienteSessao(models.Model): # ExpedienteSessaoPlenaria return '%s - %s' % (self.tipo, self.sessao_plenaria) -@reversion.register() class OcorrenciaSessao(models.Model): # OcorrenciaSessaoPlenaria sessao_plenaria = models.OneToOneField(SessaoPlenaria, on_delete=models.PROTECT) @@ -475,7 +465,6 @@ class OcorrenciaSessao(models.Model): # OcorrenciaSessaoPlenaria return '%s - %s' % (self.sessao_plenaria, self.conteudo) -@reversion.register() class ConsideracoesFinais(models.Model): # ConsideracoesFinaisSessaoPlenaria sessao_plenaria = models.OneToOneField(SessaoPlenaria, on_delete=models.PROTECT) @@ -491,7 +480,6 @@ class ConsideracoesFinais(models.Model): # ConsideracoesFinaisSessaoPlenaria return '%s - %s' % (self.sessao_plenaria, self.conteudo) -@reversion.register() class IntegranteMesa(models.Model): # MesaSessaoPlenaria sessao_plenaria = models.ForeignKey(SessaoPlenaria, on_delete=models.CASCADE) @@ -507,7 +495,6 @@ class IntegranteMesa(models.Model): # MesaSessaoPlenaria return '%s - %s' % (self.cargo, self.parlamentar) -@reversion.register() class AbstractOrador(models.Model): # Oradores sessao_plenaria = models.ForeignKey(SessaoPlenaria, on_delete=models.CASCADE) @@ -546,7 +533,6 @@ class AbstractOrador(models.Model): # Oradores return result -@reversion.register() class Orador(AbstractOrador): # Oradores class Meta: @@ -555,7 +541,6 @@ class Orador(AbstractOrador): # Oradores ordering = ('id',) -@reversion.register() class OradorExpediente(AbstractOrador): # OradoresExpediente class Meta: @@ -564,7 +549,6 @@ class OradorExpediente(AbstractOrador): # OradoresExpediente ordering = ('id',) -@reversion.register() class OradorOrdemDia(AbstractOrador): # OradoresOrdemDia class Meta: @@ -573,7 +557,6 @@ class OradorOrdemDia(AbstractOrador): # OradoresOrdemDia ordering = ('id',) -@reversion.register() class OrdemDia(AbstractOrdemDia): class Meta: @@ -582,7 +565,6 @@ class OrdemDia(AbstractOrdemDia): ordering = ['numero_ordem'] -@reversion.register() class PresencaOrdemDia(models.Model): # OrdemDiaPresenca sessao_plenaria = models.ForeignKey(SessaoPlenaria, on_delete=models.CASCADE) @@ -600,7 +582,6 @@ class PresencaOrdemDia(models.Model): # OrdemDiaPresenca 'parlamentar': self.parlamentar} -@reversion.register() class TipoResultadoVotacao(models.Model): NATUREZA_CHOICES = Choices( ('A', 'aprovado', 'Aprovado'), @@ -620,7 +601,6 @@ class TipoResultadoVotacao(models.Model): return self.nome -@reversion.register() class RegistroVotacao(models.Model): tipo_resultado_votacao = models.ForeignKey( TipoResultadoVotacao, @@ -679,7 +659,6 @@ class RegistroVotacao(models.Model): '{}, {}'. format(self.ordem, self.expediente)) -@reversion.register() class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar ''' As colunas ordem e expediente são redundantes, levando em consideração @@ -724,7 +703,6 @@ class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar 'votacao': self.votacao, 'parlamentar': self.parlamentar} -@reversion.register() class SessaoPlenariaPresenca(models.Model): sessao_plenaria = models.ForeignKey(SessaoPlenaria, on_delete=models.CASCADE) @@ -757,7 +735,6 @@ ORDENACAO_RESUMO = [ ] -@reversion.register() class ResumoOrdenacao(models.Model): ''' Tabela para registrar em qual ordem serão renderizados os componentes @@ -837,7 +814,6 @@ class ResumoOrdenacao(models.Model): return 'Ordenação do Resumo de uma Sessão' -@reversion.register() class TipoRetiradaPauta(models.Model): descricao = models.CharField(max_length=150, verbose_name=_('Descrição')) @@ -850,7 +826,6 @@ class TipoRetiradaPauta(models.Model): return self.descricao -@reversion.register() class TipoJustificativa(models.Model): descricao = models.CharField(max_length=150, verbose_name=_('Descrição')) @@ -863,7 +838,6 @@ class TipoJustificativa(models.Model): return self.descricao -@reversion.register() class JustificativaAusencia(models.Model): TIPO_AUSENCIA_CHOICES = Choices( (1, 'materia', 'Matéria'), @@ -988,7 +962,6 @@ class RetiradaPauta(models.Model): '{}, {}'. format(self.ordem, self.expediente)) -@reversion.register() class RegistroLeitura(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) ordem = models.ForeignKey(OrdemDia, @@ -1037,7 +1010,6 @@ class RegistroLeitura(models.Model): '{}, {}'. format(self.ordem, self.expediente)) -@reversion.register() class Correspondencia(models.Model): TIPO_CHOICES = Choices( (1, 'recebida', 'Recebida'), diff --git a/sapl/settings.py b/sapl/settings.py index 59298311a..978d81531 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -88,9 +88,6 @@ INSTALLED_APPS = ( 'easy_thumbnails', 'image_cropping', - 'reversion', - 'reversion_compare', - 'haystack', 'django.contrib.postgres', 'speedinfo', @@ -127,7 +124,6 @@ HAYSTACK_CONNECTIONS = { } MIDDLEWARE = [ - 'reversion.middleware.RevisionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', diff --git a/sapl/utils.py b/sapl/utils.py index 928e7fe7c..88eba024c 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -37,7 +37,6 @@ from easy_thumbnails import source_generators from floppyforms import ClearableFileInput import magic import requests -from reversion_compare.admin import CompareVersionAdmin from unipath.path import Path from sapl.crispy_layout_mixin import (form_actions, SaplFormHelper, @@ -363,7 +362,7 @@ def register_all_models_in_admin(module_name, exclude_list=[]): app = apps.get_app_config(appname) for model in app.get_models(): - class CustomModelAdmin(CompareVersionAdmin): + class CustomModelAdmin(admin.ModelAdmin): list_display = [f.name for f in model._meta.fields if f.name != 'id' and f.name not in exclude_list] diff --git a/setup.py b/setup.py index 6116aa85c..0216d13eb 100644 --- a/setup.py +++ b/setup.py @@ -19,8 +19,6 @@ install_requires = [ 'django-floppyforms==1.7.0', 'django-extra-views==0.12.0', 'django-model-utils==3.1.2', - 'django-reversion==3.0.2', - 'django-reversion-compare==0.8.6', 'django-speedinfo==1.4.0', 'django-extensions==2.1.4', 'django-image-cropping==1.2.0',