Browse Source

Salva apenas arquivos diferentes para o annex

pull/1914/head
Marcio Mazza 7 years ago
parent
commit
87c7e82fd2
  1. 150
      sapl/legacy/scripts/exporta_zope/exporta_zope.py

150
sapl/legacy/scripts/exporta_zope/exporta_zope.py

@ -5,6 +5,8 @@
# 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
@ -16,9 +18,10 @@ import git
import magic
import pyaml
import yaml
from unipath import Path
import ZODB.DB
import ZODB.FileStorage
from unipath import Path
from ZODB.broken import Broken
EXTENSOES = {
@ -62,29 +65,25 @@ def br(obj):
return obj
def guess_extension(caminho):
mime = magic.from_file(caminho, mime=True)
def guess_extension(fullname, buffer):
mime = magic.from_buffer(buffer, mime=True)
try:
return EXTENSOES[mime]
except KeyError as e:
msg = '\n'.join([
'Extensão não conhecida para o arquivo:',
caminho,
'E mimetype:',
mime,
' Algumas possibilidades são:', ] +
possibilidades = '\n'.join(
[" '{}': '{}',".format(mime, ext)
for ext in mimetypes.guess_all_extensions(mime)] +
['Atualize o código do dicionário EXTENSOES!']
)
for ext in mimetypes.guess_all_extensions(mime)])
msg = '''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)
print(msg)
raise Exception(msg, e)
nomes_arquivos_exportados = {}
def dump_file(doc, path):
def dump_file(doc, path, salvar):
name = doc['__name__']
fullname = os.path.join(path, name)
@ -104,23 +103,11 @@ def dump_file(doc, path):
doc['data'] = pdata
pdata = doc
with open(fullname, 'w') as arq:
while pdata:
arq.write(pdata.pop('data'))
pdata = br(pdata.pop('next', None))
base, original_extension = os.path.splitext(fullname)
extension = guess_extension(fullname)
if extension == '.xml' and original_extension in ['.xsl', '.xslt']:
# não trocamos as extensões XSL e XSLT
final_name = fullname
else:
# trocamos a extensão pela adivinhada
final_name = base + extension
os.rename(fullname, final_name)
nomes_arquivos_exportados[fullname] = final_name
print(final_name)
output = cStringIO.StringIO()
while pdata:
output.write(pdata.pop('data'))
pdata = br(pdata.pop('next', None))
salvar(fullname, output.getvalue())
return name
@ -165,7 +152,7 @@ def logando_nao_identificados():
print('#' * 80)
def dump_folder(folder, path='', enum=enumerate_folder):
def dump_folder(folder, path, salvar, enum=enumerate_folder):
name = folder['id']
path = os.path.join(path, name)
if not os.path.exists(path):
@ -175,7 +162,7 @@ def dump_folder(folder, path='', enum=enumerate_folder):
if dump == '?':
nao_identificados[meta_type].append(path + '/' + id)
elif dump:
id_interno = dump(obj, path)
id_interno = dump(obj, path, salvar)
assert id == id_interno
return name
@ -211,18 +198,16 @@ def read_sde(element):
return data
def save_as_yaml(path, name, obj):
def save_as_yaml(path, name, obj, salvar):
fullname = os.path.join(path, name)
with open(fullname, 'w') as arquivo:
yaml.safe_dump(obj, arquivo, allow_unicode=True)
print(fullname)
return fullname
conteudo = yaml.safe_dump(obj, allow_unicode=True)
salvar(fullname, conteudo)
def dump_sde(strdoc, path, tipo):
def dump_sde(strdoc, path, salvar, tipo):
id = strdoc['id']
sde = read_sde(strdoc)
save_as_yaml(path, '{}.{}.yaml'.format(id, tipo), sde)
save_as_yaml(path, '{}.{}.yaml'.format(id, tipo), sde, salvar)
return id
@ -243,7 +228,7 @@ DUMP_FUNCTIONS = {
def get_app(data_fs_path):
storage = ZODB.FileStorage.FileStorage(data_fs_path)
storage = ZODB.FileStorage.FileStorage(data_fs_path, read_only=True)
db = ZODB.DB(storage)
connection = db.open()
root = connection.root()
@ -265,60 +250,79 @@ def find_sapl(app):
return sapl
def dump_propriedades(docs, path, encoding='iso-8859-1'):
def dump_propriedades(docs, path, salvar, encoding='iso-8859-1'):
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: p.decode(encoding) if isinstance(p, str) else p
for id, p in props.items()}
save_as_yaml(path, 'sapl_documentos/propriedades.yaml', props)
save_as_yaml(path, 'sapl_documentos/propriedades.yaml', props, salvar)
def dump_usuarios(sapl, path):
def dump_usuarios(sapl, path, salvar):
users = br(br(sapl['acl_users'])['data'])
users = {k: br(v) for k, v in users['data'].items()}
save_as_yaml(path, 'usuarios.yaml', users)
def grava_nomes_arquivos_exportados(destino):
"""Grava nomes dos arquivos exportados (originais -> definitivos)
"""
destino = Path(destino)
def rel(caminho):
return str(destino.rel_path_to(caminho))
with open(destino.child('arquivos_exportados.yaml'), 'w') as arq:
nomes = {rel(k): rel(v) for k, v in nomes_arquivos_exportados.items()}
pyaml.dump(nomes, arq)
save_as_yaml(path, 'usuarios.yaml', users, salvar)
def _dump_sapl(data_fs_path, destino='../../../../media'):
def _dump_sapl(data_fs_path, destino, salvar):
assert Path(data_fs_path).exists()
app, close_db = get_app(data_fs_path)
nomes_arquivos_exportados.clear() # apaga nomes dos arquivos migrados
try:
sapl = find_sapl(app)
# extrai folhas XSLT
dump_folder(br(sapl['XSLT']), destino)
dump_folder(br(sapl['XSLT']), destino, salvar)
# extrai usuários com suas senhas e perfis
dump_usuarios(sapl, destino)
dump_usuarios(sapl, destino, salvar)
# extrai documentos
docs = br(sapl['sapl_documentos'])
with logando_nao_identificados():
dump_folder(docs, destino)
dump_propriedades(docs, destino)
dump_folder(docs, destino, salvar)
dump_propriedades(docs, destino, salvar)
finally:
close_db()
grava_nomes_arquivos_exportados(destino)
DIR_DADOS_MIGRACAO = Path('~/migracao_sapl/').expand()
def repo_execute(repo, cmd):
return repo.git.execute(cmd.split())
def repo_execute(repo, cmd, *args):
return repo.git.execute(cmd.split() + list(args))
def get_annex_hashes(repo):
hashes = repo_execute(
repo, 'git annex find', '--format=${keyname}\n', '--include=*')
return {os.path.splitext(h)[0] for h in hashes.splitlines()}
def ajusta_extensao(fullname, conteudo):
base, extensao = os.path.splitext(fullname)
if extensao not in ['.xsl', '.xslt', '.yaml']:
# não trocamos as extensões XSL, XSLT e YAML
extensao = guess_extension(fullname, conteudo)
return base + extensao
def build_salvar(repo):
"""Constroi função salvar que pula arquivos que já estão no annex
"""
hashes = get_annex_hashes(repo)
def salvar(fullname, conteudo):
sha = hashlib.sha256()
sha.update(conteudo)
if sha.hexdigest() not in hashes:
fullname = ajusta_extensao(fullname, conteudo)
if os.path.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):
@ -329,9 +333,13 @@ def dump_sapl(sigla):
destino = DIR_DADOS_MIGRACAO.child('repos', nome_banco_legado)
destino.mkdir(parents=True)
repo = git.Repo.init(destino)
_dump_sapl(data_fs_path, destino)
# grava mundaças
repo_execute(repo, 'git annex init')
repo_execute(repo, 'git config annex.thin true')
salvar = build_salvar(repo)
_dump_sapl(data_fs_path, destino, salvar)
# grava mundaças
repo_execute(repo, 'git annex add sapl_documentos')
repo.git.add(A=True)
if 'master' not in repo.heads or repo.index.diff('HEAD'):

Loading…
Cancel
Save