moan-ark/pasta_publica/Mjson/processador.php

261 lines
8.4 KiB
PHP

<?php
function buscarOuCriarJson($path_item, $variacao, $usuario, $repositorio, $branch, $site_gitea) {
header('Content-Type: application/json; charset=utf-8');
// URL RAW
$url_markdown_raw = "$site_gitea/$usuario/$repositorio/raw/branch/$branch/$path_item/README.md";
// Nome do arquivo local
$nome_base = str_replace('/', '_b_', $path_item);
if ($variacao) {
$nome_base .= "_p_" . $variacao;
}
$caminho_json_local = __DIR__ . '/' . $nome_base . ".json";
// Verificação de Datas
$precisa_atualizar = false;
if (!file_exists($caminho_json_local)) {
$precisa_atualizar = true;
} else {
$data_local = filemtime($caminho_json_local);
$data_remota = _obterDataModificacaoRemota($url_markdown_raw);
if ($data_remota === false || $data_remota > $data_local) {
$precisa_atualizar = true;
}
}
// Ação
if ($precisa_atualizar) {
$conteudo_md = @file_get_contents($url_markdown_raw);
if ($conteudo_md === false) {
echo json_encode(['ok' => false, 'msg' => 'Erro ao baixar MD.', 'url' => $url_markdown_raw]);
exit;
}
$config = [
'usuario' => $usuario,
'repositorio' => $repositorio,
'branch' => $branch,
'site_gitea' => $site_gitea
];
// Processa o Scrapping
$dados_processados = _realizarScraping($conteudo_md, $variacao, $path_item, $config);
// Gera o JSON final
$json_final = json_encode($dados_processados, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
file_put_contents($caminho_json_local, $json_final);
echo $json_final;
exit;
} else {
readfile($caminho_json_local);
exit;
}
}
// --- Funções de Parsing ---
function _realizarScraping($markdown, $variacao, $path_original, $config) {
// Configura data para Horário de Brasília (GMT-3)
try {
$dataBrasilia = new DateTime('now', new DateTimeZone('America/Sao_Paulo'));
$dataGeracao = $dataBrasilia->format('Y-m-d H:i:s');
} catch (Exception $e) {
// Fallback caso o servidor não tenha timezone configurado
$dataGeracao = date('Y-m-d H:i:s') . ' (Server Time)';
}
$json = [
'meta' => [
'path_original' => $path_original,
'variacao' => $variacao,
'gerado_em' => $dataGeracao
]
];
// Mapeamento de campos especiais que vão para a RAIZ
$mapeamentoEspeciais = [
'identificador_do_registro' => 'ark',
'visualizacao_publica_ark' => 'link_visualizacao_publica',
'visualizacao_no_meta_museu_da_matematica_editora_moan' => 'link_meta_museu',
'denominacao' => 'titulo',
'outras_denominacoes' => 'outras_denominacoes',
'tipo_de_bem_objeto_original' => 'tipo_bem',
'categoria_museologica' => 'categoria_museologica',
'subcategoria' => 'subcategoria'
];
$linhas = explode("\n", $markdown);
$secaoAtual = 'inicio';
$chaveAtual = null;
$dadosSecoes = [];
$dadosSecoes[$secaoAtual] = [];
foreach ($linhas as $linha) {
$linha = trim($linha);
if ($linha === '') continue;
// 1. TÍTULOS (##)
if (preg_match('/^#{2,4}\s+(.*)$/', $linha, $matches)) {
$nomeSecaoRaw = $matches[1];
$secaoAtual = _limparChave($nomeSecaoRaw);
$chaveAtual = null;
if (!isset($dadosSecoes[$secaoAtual])) {
$dadosSecoes[$secaoAtual] = [];
}
continue;
}
// 2. CHAVE-VALOR (**Chave:** Valor)
if (preg_match('/.*\*\*(.+?):\*\*\s*(.*)$/', $linha, $matches)) {
$chaveRaw = $matches[1];
$valorInicial = $matches[2];
$chaveLimpa = _limparChave($chaveRaw);
$valorLimpo = _limparTextoGeral($valorInicial);
if (array_key_exists($chaveLimpa, $mapeamentoEspeciais)) {
$chaveRaiz = $mapeamentoEspeciais[$chaveLimpa];
$json[$chaveRaiz] = $valorLimpo;
$chaveAtual = null;
} else {
$chaveAtual = $chaveLimpa;
$dadosSecoes[$secaoAtual][$chaveAtual] = $valorLimpo;
}
continue;
}
// 3. ITENS DE LISTA (- Item)
if (preg_match('/^-\s+(.*)$/', $linha, $matches) && !preg_match('/^-{3,}$/', $linha)) {
$itemLista = _limparTextoGeral($matches[1]);
if ($chaveAtual) {
if (!is_array($dadosSecoes[$secaoAtual][$chaveAtual])) {
$valAtual = $dadosSecoes[$secaoAtual][$chaveAtual];
if ($valAtual === '') {
$dadosSecoes[$secaoAtual][$chaveAtual] = [];
} else {
$dadosSecoes[$secaoAtual][$chaveAtual] = [$valAtual];
}
}
$dadosSecoes[$secaoAtual][$chaveAtual][] = $itemLista;
} else {
if (!isset($dadosSecoes[$secaoAtual]['lista_geral'])) {
$dadosSecoes[$secaoAtual]['lista_geral'] = [];
}
$dadosSecoes[$secaoAtual]['lista_geral'][] = $itemLista;
}
continue;
}
// 4. TEXTO GERAL
if (substr($linha, 0, 3) !== '```') {
$textoLimpo = _limparTextoGeral($linha);
if ($textoLimpo === '') continue;
if ($chaveAtual) {
$valAtual = $dadosSecoes[$secaoAtual][$chaveAtual];
if (is_array($valAtual)) {
$chaveAtual = null;
goto texto_geral_rotulo;
}
if ($valAtual !== '') {
$dadosSecoes[$secaoAtual][$chaveAtual] .= " " . $textoLimpo;
} else {
$dadosSecoes[$secaoAtual][$chaveAtual] = $textoLimpo;
}
} else {
texto_geral_rotulo:
if (!isset($dadosSecoes[$secaoAtual]['texto_geral'])) {
$dadosSecoes[$secaoAtual]['texto_geral'] = '';
}
$sep = ($dadosSecoes[$secaoAtual]['texto_geral'] !== '') ? " " : "";
$dadosSecoes[$secaoAtual]['texto_geral'] .= $sep . $textoLimpo;
}
}
}
// --- MONTAGEM DO JSON FINAL ---
foreach ($dadosSecoes as $nomeSecao => $conteudo) {
if ($nomeSecao === 'inicio' && empty($conteudo)) continue;
if (empty($conteudo)) continue;
if (count($conteudo) === 1 && isset($conteudo['lista_geral'])) {
$json[$nomeSecao] = $conteudo['lista_geral'];
}
elseif (count($conteudo) === 1 && isset($conteudo['texto_geral'])) {
$json[$nomeSecao] = $conteudo['texto_geral'];
}
else {
$objetoLimpo = [];
foreach ($conteudo as $k => $v) {
if ($k === 'lista_geral') {
$objetoLimpo['itens'] = $v;
} elseif ($k === 'texto_geral') {
$objetoLimpo['descricao_geral'] = $v;
} else {
$objetoLimpo[$k] = $v;
}
}
$json[$nomeSecao] = $objetoLimpo;
}
}
return $json;
}
/**
* LIMPEZA AGRESSIVA PARA CHAVES
*/
function _limparChave($texto) {
// 1. Remove qualquer caractere que NÃO seja Letra, Número ou Espaço
$texto = preg_replace('/[^\p{L}\p{N}\s]/u', '', $texto);
// 2. Transliteração
$texto = iconv('UTF-8', 'ASCII//TRANSLIT', $texto);
// 3. Formatação
$texto = trim($texto);
$texto = strtolower($texto);
$texto = preg_replace('/\s+/', '_', $texto);
return $texto;
}
/**
* Limpeza para Valores (Mantém pontuação básica, remove emojis)
*/
function _limparTextoGeral($texto) {
// Remove apenas símbolos gráficos e emojis
$texto = preg_replace('/[\p{So}\p{Sk}\p{Sm}\p{Sc}\p{Co}\p{Cn}]/u', '', $texto);
return trim($texto);
}
function _obterDataModificacaoRemota($url) {
$options = [ 'http' => [ 'method' => 'HEAD', 'header' => "User-Agent: PHP-Script\r\n" ] ];
$context = stream_context_create($options);
$headers = @get_headers($url, 1, $context);
if ($headers && isset($headers['Last-Modified'])) {
return strtotime($headers['Last-Modified']);
}
return false;
}
?>