Browse Source

Adapta migração de docs para nova exportação do zope

Fix #1627
pull/1704/head
Marcio Mazza 7 years ago
parent
commit
948ddd45d7
  1. 3
      sapl/base/models.py
  2. 138
      sapl/legacy/migracao_documentos.py

3
sapl/base/models.py

@ -5,6 +5,7 @@ from django.db import models
from django.db.models.signals import post_migrate from django.db.models.signals import post_migrate
from django.db.utils import DEFAULT_DB_ALIAS from django.db.utils import DEFAULT_DB_ALIAS
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from sapl.utils import (LISTA_DE_UFS, YES_NO_CHOICES, from sapl.utils import (LISTA_DE_UFS, YES_NO_CHOICES,
get_settings_auth_user_model, models_with_gr_for_model) get_settings_auth_user_model, models_with_gr_for_model)
@ -38,7 +39,7 @@ class CasaLegislativa(models.Model):
max_length=100, blank=True, verbose_name=_('Fax')) max_length=100, blank=True, verbose_name=_('Fax'))
logotipo = models.ImageField( logotipo = models.ImageField(
blank=True, blank=True,
upload_to='sapl/casa/logotipo/', upload_to='sapl/public/casa/logotipo/',
verbose_name=_('Logotipo')) verbose_name=_('Logotipo'))
endereco_web = models.URLField( endereco_web = models.URLField(
max_length=100, blank=True, verbose_name=_('HomePage')) max_length=100, blank=True, verbose_name=_('HomePage'))

138
sapl/legacy/migracao_documentos.py

@ -1,10 +1,10 @@
import mimetypes import mimetypes
import os import os
import re import re
from glob import glob
import yaml import yaml
import magic
from sapl.base.models import CasaLegislativa from sapl.base.models import CasaLegislativa
from sapl.legacy.migration import exec_legado, warn from sapl.legacy.migration import exec_legado, warn
from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa, from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa,
@ -17,82 +17,82 @@ from sapl.sessao.models import SessaoPlenaria
from sapl.settings import MEDIA_ROOT from sapl.settings import MEDIA_ROOT
# MIGRAÇÃO DE DOCUMENTOS ################################################### # MIGRAÇÃO DE DOCUMENTOS ###################################################
EXTENSOES = {
'application/msword': '.doc',
'application/pdf': '.pdf', def get_ano(obj):
'application/vnd.oasis.opendocument.text': '.odt', return [obj.ano]
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx', # noqa
'application/xml': '.xml',
'text/xml': '.xml', def ___(obj):
'application/zip': '.zip', return []
'image/jpeg': '.jpeg',
'image/png': '.png',
'text/html': '.html',
'text/rtf': '.rtf',
'text/x-python': '.py',
'text/plain': '.txt',
# sem extensao
'application/octet-stream': '', # binário
'inode/x-empty': '', # vazio
}
DOCS = { DOCS = {
CasaLegislativa: [ CasaLegislativa: [
('logotipo', ('logotipo',
'props_sapl/logo_casa.gif', 'props_sapl/{}.*',
'casa/logotipo/logo_casa.gif') 'public/casa/logotipo/',
___)
], ],
Parlamentar: [ Parlamentar: [
('fotografia', ('fotografia',
'parlamentar/fotos/{}_foto_parlamentar', 'parlamentar/fotos/{}_foto_parlamentar',
'public/parlamentar/{0}/{0}_foto_parlamentar{1}') 'public/parlamentar/{0}/',
___)
], ],
MateriaLegislativa: [ MateriaLegislativa: [
('texto_original', ('texto_original',
'materia/{}_texto_integral', 'materia/{}_texto_integral',
'public/materialegislativa/{2}/{0}/{0}_texto_integral{1}') 'public/materialegislativa/{1}/{0}/',
get_ano)
], ],
DocumentoAcessorio: [ DocumentoAcessorio: [
('arquivo', ('arquivo',
'materia/{}', 'materia/{}',
'public/documentoacessorio/{2}/{0}/{0}{1}') 'public/documentoacessorio/{1}/{0}/',
lambda obj: [obj.materia.ano])
], ],
NormaJuridica: [ NormaJuridica: [
('texto_integral', ('texto_integral',
'norma_juridica/{}_texto_integral', 'norma_juridica/{}_texto_integral',
'public/normajuridica/{2}/{0}/{0}_texto_integral{1}') 'public/normajuridica/{1}/{0}/',
get_ano)
], ],
SessaoPlenaria: [ SessaoPlenaria: [
('upload_ata', ('upload_ata',
'ata_sessao/{}_ata_sessao', 'ata_sessao/{}_ata_sessao',
'public/sessaoplenaria/{0}/ata/{0}_ata_sessao{1}'), 'public/sessaoplenaria/{0}/ata/',
___),
('upload_anexo', ('upload_anexo',
'anexo_sessao/{}_texto_anexado', 'anexo_sessao/{}_texto_anexado',
'public/sessaoplenaria/{0}/anexo/{0}_texto_anexado{1}') 'public/sessaoplenaria/{0}/anexo/',
___)
], ],
Proposicao: [ Proposicao: [
('texto_original', ('texto_original',
'proposicao/{}', 'proposicao/{}',
'private/proposicao/{0}/{0}{1}') 'private/proposicao/{0}/',
get_ano)
], ],
DocumentoAdministrativo: [ DocumentoAdministrativo: [
('texto_integral', ('texto_integral',
'administrativo/{}_texto_integral', 'administrativo/{}_texto_integral',
'private/documentoadministrativo/{0}/{0}_texto_integral{1}') 'private/documentoadministrativo/{0}/',
get_ano)
], ],
DocumentoAcessorioAdministrativo: [ DocumentoAcessorioAdministrativo: [
('arquivo', ('arquivo',
'administrativo/{}', 'administrativo/{}',
'private/documentoacessorioadministrativo/{0}/' 'private/documentoacessorioadministrativo/{0}/',
'{0}_acessorio_administrativo{1}') ___)
], ],
} }
DOCS = {model: [(campo, DOCS = {model: [(campo,
os.path.join('sapl_documentos', origem), os.path.join('sapl_documentos', origem),
os.path.join('sapl', destino)) os.path.join('sapl', destino),
for campo, origem, destino in campos] get_extra_args)
for campo, origem, destino, get_extra_args in campos]
for model, campos in DOCS.items()} for model, campos in DOCS.items()}
@ -128,59 +128,32 @@ def migrar_propriedades_da_casa():
('informacao_geral', 'txt_informacao_geral')] ('informacao_geral', 'txt_informacao_geral')]
for campo, prop in campos_para_propriedades: for campo, prop in campos_para_propriedades:
setattr(casa, campo, propriedades[prop]) setattr(casa, campo, propriedades[prop])
# Localidade # Localidade
sql_localidade = ''' sql_localidade = '''
select nom_localidade, sgl_uf from localidade select nom_localidade, sgl_uf from localidade
where cod_localidade = {}'''.format(propriedades['cod_localidade']) where cod_localidade = {}'''.format(propriedades['cod_localidade'])
[(casa.municipio, casa.uf)] = exec_legado(sql_localidade) [(casa.municipio, casa.uf)] = exec_legado(sql_localidade)
casa.save()
def migrar_logotipo_da_casa():
print('#### Migrando logotipo da casa ####')
[(_, origem, destino)] = DOCS[CasaLegislativa]
props_sapl = os.path.dirname(origem)
# a pasta props_sapl deve conter apenas o origem e metadatas!
# Edit: Aparentemente há diretório que contém properties ao invés de
# metadata. O assert foi modificado para essa situação.
sobrando = set(os.listdir(em_media(props_sapl))) - {
'logo_casa.gif', '.metadata', 'logo_casa.gif.metadata',
'.properties', 'logo_casa.gif.properties', '.objects'}
if sobrando:
warn('Os seguintes arquivos da pasta props_sapl foram ignorados: ' +
', '.join(sobrando))
print('.... Migrando logotipo da casa ....')
[(_, origem, destino, __)] = DOCS[CasaLegislativa]
# a extensão do logo pode ter sido ajustada pelo tipo real do arquivo
id_logo = os.path.splitext(propriedades['id_logo'])[0]
[origem] = glob(em_media(origem.format(id_logo)))
destino = os.path.join(destino, os.path.basename(origem))
mover_documento(origem, destino) mover_documento(origem, destino)
casa = CasaLegislativa.objects.first()
casa.logotipo = destino casa.logotipo = destino
casa.save() casa.save()
os.remove(caminho)
def get_extensao(caminho):
mime = magic.from_file(caminho, mime=True)
try:
return EXTENSOES[mime]
except KeyError as e:
raise Exception('\n'.join([
'Extensão não conhecida para o arquivo:',
caminho,
'E mimetype:',
mime,
' Algumas possibilidades são:', ] +
[" '{}': '{}',".format(mime, ext)
for ext in mimetypes.guess_all_extensions(mime)] +
['Atualize o código do dicionário EXTENSOES!']
)) from e
def migrar_docs_por_ids(model): def migrar_docs_por_ids(model):
for campo, base_origem, base_destino in DOCS[model]: for campo, base_origem, base_destino, get_extra_args in DOCS[model]:
print('#### Migrando {} de {} ####'.format(campo, model.__name__)) print('#### Migrando {} de {} ####'.format(campo, model.__name__))
dir_origem, nome_origem = os.path.split(em_media(base_origem)) dir_origem, nome_origem = os.path.split(em_media(base_origem))
pat = re.compile('^{}\.\w+$'.format(nome_origem.format('(\d+)'))) nome_origem = nome_origem.format('(\d+)')
pat = re.compile('^{}\.\w+$'.format(nome_origem))
if not os.path.isdir(dir_origem): if not os.path.isdir(dir_origem):
print(' >>> O diretório {} não existe! Abortado.'.format( print(' >>> O diretório {} não existe! Abortado.'.format(
@ -197,19 +170,12 @@ def migrar_docs_por_ids(model):
obj = model.objects.get(pk=id) obj = model.objects.get(pk=id)
except model.DoesNotExist: except model.DoesNotExist:
msg = ' {} (pk={}) não encontrado para documento em [{}]' msg = ' {} (pk={}) não encontrado para documento em [{}]'
print(msg.format( print(msg.format(model.__name__, id, origem))
model.__name__, id, origem))
else: else:
extensao = get_extensao(origem) destino = os.path.join(
if hasattr(obj, "ano"): base_destino.format(id, *get_extra_args(obj)),
destino = base_destino.format(id, extensao, obj.ano) os.path.basename(origem))
elif isinstance(obj, DocumentoAcessorio):
destino = base_destino.format(
id, extensao, obj.materia.ano)
else:
destino = base_destino.format(id, extensao)
mover_documento(origem, destino) mover_documento(origem, destino)
setattr(obj, campo, destino) setattr(obj, campo, destino)
obj.save() obj.save()
@ -217,15 +183,13 @@ def migrar_docs_por_ids(model):
def migrar_documentos(): def migrar_documentos():
# aqui supomos que uma pasta chamada sapl_documentos está em MEDIA_ROOT # aqui supomos que uma pasta chamada sapl_documentos está em MEDIA_ROOT
# com o conteúdo da pasta de mesmo nome do zope # com o conteúdo da pasta de mesmo nome do zope
# Os arquivos da pasta serão MOVIDOS para a nova estrutura e a pasta será # Os arquivos da pasta serão MOVIDOS para a nova estrutura!
# apagada # A pasta, após conferência do que não foi migrado, deve ser apagada.
# #
# Isto significa que para rodar novamente esta função é preciso # Isto significa que para rodar novamente esta função é preciso
# restaurar a pasta sapl_documentos ao estado inicial # restaurar a pasta sapl_documentos ao estado inicial
# esta ordem é importante
migrar_propriedades_da_casa() migrar_propriedades_da_casa()
migrar_logotipo_da_casa()
for model in [ for model in [
Parlamentar, Parlamentar,

Loading…
Cancel
Save