diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index 270c90583..33a007230 100755 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -13,6 +13,7 @@ import sys from collections import defaultdict from contextlib import contextmanager from functools import partial +from os.path import exists import git import magic @@ -147,7 +148,7 @@ 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 = br(folder.get(id, None)) + obj = folder.get(id, None) except POSKeyError: print('#' * 80) print('#' * 80) @@ -170,7 +171,7 @@ def enumerate_btree(folder): tree = folder['_tree'] contagem_real = 0 # para o caso em que não haja itens for contagem_real, (id, obj) in enumerate(tree.iteritems(), start=1): - obj, meta_type = br(obj), type(obj).__name__ + meta_type = type(obj).__name__ yield id, obj, meta_type # verificação de consistência if contagem_esperada != contagem_real: @@ -197,10 +198,10 @@ def logando_nao_identificados(): print('#' * 80) -def dump_folder(folder, path, salvar, enum=enumerate_folder): +def dump_folder(folder, path, salvar, mtimes, enum=enumerate_folder): name = folder['id'] path = os.path.join(path, name) - if not os.path.exists(path): + if not exists(path): os.makedirs(path) for id, obj, meta_type in enum(folder): # pula pastas *_old (presentes em várias bases) @@ -210,8 +211,16 @@ def dump_folder(folder, path, salvar, enum=enumerate_folder): if dump == '?': nao_identificados[meta_type].append(path + '/' + id) elif dump: - id_interno = dump(obj, path, salvar) - assert id == id_interno + if isinstance(dump, partial) and dump.func == dump_folder: + dump(br(obj), path, salvar, mtimes) + 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): + id_interno = dump(br(obj), path, salvar) + assert id == id_interno + mtimes[fullname] = mtime return name @@ -223,7 +232,7 @@ def read_sde(element): def read_properties(): for id, obj, meta_type in enumerate_properties(element): - yield id, decode_iso8859(obj) + yield id, decode_iso8859(br(obj)) def read_children(): for id, obj, meta_type in enumerate_folder(element): @@ -237,7 +246,7 @@ def read_sde(element): # ignoramos os scrips python de eventos dos templates yield {'id': id, 'meta_type': meta_type, - 'dados': read_sde(obj)} + 'dados': read_sde(br(obj))} data = dict(read_properties()) children = list(read_children()) @@ -335,9 +344,12 @@ def dump_usuarios(sapl, path, salvar): save_as_yaml(path, 'usuarios.yaml', users, salvar) -def _dump_sapl(data_fs_path, documentos_fs_path, destino, salvar): - assert Path(data_fs_path).exists() - assert Path(documentos_fs_path).exists() +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: @@ -352,12 +364,12 @@ def _dump_sapl(data_fs_path, documentos_fs_path, destino, salvar): sapl = find_sapl(app) # extrai folhas XSLT if 'XSLT' in sapl: - dump_folder(br(sapl['XSLT']), destino, salvar) + dump_folder(br(sapl['XSLT']), destino, salvar, mtimes) # extrai documentos docs = br(sapl['sapl_documentos']) with logando_nao_identificados(): - dump_folder(docs, destino, salvar) + dump_folder(docs, destino, salvar, mtimes) dump_propriedades(docs, destino, salvar) finally: close_db() @@ -392,7 +404,7 @@ def build_salvar(repo): print('- hash encontrado - {}'.format(fullname)) else: fullname = ajusta_extensao(fullname, conteudo) - if os.path.exists(fullname): + if exists(fullname): # destrava arquivo pré-existente (o conteúdo mudou) repo_execute(repo, 'git annex unlock', fullname) with open(fullname, 'w') as arq: @@ -409,8 +421,8 @@ def dump_sapl(sigla): 'datafs', '{}_cm_{}.fs'.format(prefixo, sigla)) for prefixo in ('Data', 'DocumentosSapl')] - assert data_fs_path.exists(), 'Origem não existe: {}'.format(data_fs_path) - if not documentos_fs_path.exists(): + 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) @@ -427,12 +439,17 @@ def dump_sapl(sigla): salvar = build_salvar(repo) try: finalizado = False - _dump_sapl(data_fs_path, documentos_fs_path, destino, salvar) + arq_mtimes = Path(repo.working_dir, 'mtimes.yaml') + mtimes = yaml.load( + arq_mtimes.read_file()) 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') repo.git.add(A=True) + arq_mtimes.write_file(yaml.safe_dump(mtimes, allow_unicode=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'