(add): Adição de gestçao do Museu
This commit is contained in:
parent
2b8862c5cd
commit
d2f9414e7d
@ -21,7 +21,15 @@ Os ":" (dois pontos) serão substituídos por \_dp\_; o "." (ponto), por \_p\_ e
|
||||
|
||||
### Instruções para o prefixo M
|
||||
|
||||
O prefixo M é do Meta Museu da Matemática da Editora Moan. Ele sempre redireciona para o gitea da editora, para o repositório do museu. Ele sempre buscará um README.md em que contém os metadados, as variações, a visualização do objeto e, no mesmo diretório, os os arquivos correspondentes.
|
||||
|
||||
Se a busca pelo ARK for com a interrogação, isto é, tentando acessar os metadados, o solicitante será redirecionado para uma API que retornará um json com todos os metadados.
|
||||
|
||||
#### Sobre os nomes dos arquivos
|
||||
|
||||
Os ARKs serão pastas no gitea e as variações serão ãncoras no arquivo README.md. Os nomes das pastas deve ter o título do objeto catalogado com "_° no lugar de espaças, tudo em minúculas e o hífen "-" como separador para indicar o ARK e aí, dentro da pasta o README.md. Exemplo "osso_de_ishango-M3GD/README.md". Seguindo a natureza hierárquica dos ARKs, se for um objeto que é parte do original (mais geral), deve-se criar uma pasta dentro da original seguindo os mesmos critério e dentro dela um outro README.md.
|
||||
|
||||
Obs.: Esses ARKs não possuem apontamento. O padrão é sempre como descrito acima. Caso precise alterar, será necessário uma mudança no código.
|
||||
|
||||
## Observações
|
||||
|
||||
|
||||
@ -2,7 +2,97 @@
|
||||
|
||||
function processarPrefixo_M($NAAN, $ark_sem_NAAN, $tem_interrogacao, $resto) {
|
||||
|
||||
|
||||
$site_base = 'https://gitea.livro.online';
|
||||
$usuario = "metamuseudamatematica";
|
||||
$repositorio = "arcevo";
|
||||
$branch = "main";
|
||||
|
||||
// Constrói a URL base para o redirecionamento final (caso não seja JSON)
|
||||
$localizacao_base = $site_base . '/' . $usuario . '/' . $repositorio . '/src/branch/' . $branch . '/';
|
||||
|
||||
$variacao_arr = explode('.', $ark_sem_NAAN);
|
||||
$variacao = count($variacao_arr) > 1 ? end($variacao_arr) : false;
|
||||
$ark_procurado = '-' . ltrim($variacao_arr[0] , '/');
|
||||
|
||||
// O recursive=1 é OBRIGATÓRIO para ver pastas dentro de pastas
|
||||
$api_url = "https://gitea.livro.online/api/v1/repos/$usuario/$repositorio/git/trees/$branch?recursive=1";
|
||||
|
||||
$options = [
|
||||
"http" => [ "method" => "GET", "header" => "User-Agent: PHP-Script\r\n" ]
|
||||
];
|
||||
|
||||
$context = stream_context_create($options);
|
||||
$response = @file_get_contents($api_url, false, $context);
|
||||
$dados = json_decode($response);
|
||||
|
||||
|
||||
$destino='';
|
||||
$titulo='';
|
||||
$encontrado = false;
|
||||
|
||||
if (isset($dados->tree)) {
|
||||
foreach ($dados->tree as $item) {
|
||||
|
||||
// Se NÃO for pasta (tree), pula para o próximo item
|
||||
if ($item->type !== 'tree') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Se chegou aqui, é uma pasta.
|
||||
|
||||
|
||||
if (str_ends_with($item->path, $ark_procurado)) {
|
||||
|
||||
// Define o destino padrão (redirecionamento)
|
||||
$destino = $variacao
|
||||
? $localizacao_base . "{$item->path}/README.md#variação-{$variacao}"
|
||||
: $localizacao_base . "{$item->path}/README.md";
|
||||
|
||||
$titulo = strstr($item->path, $ark_procurado, true);
|
||||
|
||||
$encontrado = true;
|
||||
|
||||
// SE TIVER INTERROGAÇÃO -> ACIONA API JSON
|
||||
if ($tem_interrogacao) {
|
||||
|
||||
require __DIR__ . '/../Mjson/processador.php';
|
||||
|
||||
buscarOuCriarJson(
|
||||
$item->path,
|
||||
$variacao,
|
||||
$usuario,
|
||||
$repositorio,
|
||||
$branch,
|
||||
$site_base
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($encontrado) {
|
||||
return [
|
||||
'ok' => true,
|
||||
'destino' => $destino,
|
||||
'msg' => $destino . ' encontrado.',
|
||||
'titulo' => $titulo
|
||||
];
|
||||
} else {
|
||||
// Se saiu do loop sem encontrar nada, retorna FALSE
|
||||
return [
|
||||
'ok' => false,
|
||||
'destino' => '',
|
||||
'msg' => 'ark:68745/' . $ark_sem_NAAN . ' não encontrada.',
|
||||
'titulo' => ''
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@ -45,7 +45,7 @@ function processarPrefixo_eM($NAAN, $ark_sem_NAAN, $tem_interrogacao, $resto) {
|
||||
|
||||
if ($apontamento){
|
||||
|
||||
return ['ok' => true, 'destino' => $apontamento.$resto, 'msg' => $ark_formatado.' encontrado. Direcionando...', 'titulo' => $titulo];
|
||||
return ['ok' => true, 'destino' => $apontamento, 'msg' => $ark_formatado.' encontrado. Direcionando...', 'titulo' => $titulo];
|
||||
|
||||
}
|
||||
|
||||
|
||||
261
pasta_publica/Mjson/processador.php
Normal file
261
pasta_publica/Mjson/processador.php
Normal file
@ -0,0 +1,261 @@
|
||||
<?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;
|
||||
}
|
||||
?>
|
||||
@ -47,7 +47,7 @@ function init() {
|
||||
|
||||
$ark = "";
|
||||
|
||||
return ['ok'=>false,'destino'=>'','msg'=>'Nenhum ARK foi passado...','qrark'=> false,'ark_full'=>'', 'tem_interrogacao'=>false];
|
||||
return ['ok'=>false,'destino'=>'','msg'=>'Nenhum ARK foi passado...','qrark'=> false,'ark_full'=>'', 'tem_interrogacao'=>false, 'consulta_original_encontrada' => false];
|
||||
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ function init() {
|
||||
|
||||
|
||||
if ($ark === '') {
|
||||
return ['ok'=>false,'destino'=>'','msg'=>'ARK vazio.','qrark'=>$qrark,'ark_full'=>'', 'tem_interrogacao'=>false];
|
||||
return ['ok'=>false,'destino'=>'','msg'=>'ARK vazio.','qrark'=>$qrark,'ark_full'=>'', 'tem_interrogacao'=>false, 'consulta_original_encontrada' => false];
|
||||
}
|
||||
|
||||
|
||||
@ -124,7 +124,7 @@ function init() {
|
||||
//-------------------------- FIM PREFIXOS ARK --------------------------
|
||||
|
||||
if (!is_callable($buscar_ark)) {
|
||||
return ['ok'=>false,'destino'=>'','msg'=>'Prefixo ARK desconhecido.','qrark'=>$qrark,'ark_full'=>$ark_full, 'tem_interrogacao'=>$tem_interrogacao];
|
||||
return ['ok'=>false,'destino'=>'','msg'=>'Prefixo ARK desconhecido.','qrark'=>$qrark,'ark_full'=>$ark_full, 'tem_interrogacao'=>$tem_interrogacao, 'consulta_original_encontrada' => false];
|
||||
}
|
||||
|
||||
|
||||
@ -134,8 +134,9 @@ function init() {
|
||||
|
||||
$identificador_ark = false;
|
||||
|
||||
$resultado = ['ok'=>false,'destino'=>'','msg'=>'ARK não encontrado.Erro não identificado.','qrark'=>$qrark,'ark'=>$ark_full, 'tem_interrogacao'=>$tem_interrogacao];
|
||||
$resultado = ['ok'=>false,'destino'=>'','msg'=>'ARK não encontrado.Erro não identificado.','qrark'=>$qrark,'ark'=>$ark_full, 'tem_interrogacao'=>$tem_interrogacao, 'consulta_original_encontrada' => false];
|
||||
|
||||
$consulta_original_encontrada = false;
|
||||
|
||||
|
||||
do {
|
||||
@ -169,6 +170,8 @@ function init() {
|
||||
|
||||
$identificador_ark = $resultado["ok"];
|
||||
|
||||
$consulta_original_encontrada = ($index === 0);
|
||||
|
||||
$index++;
|
||||
|
||||
} while ($tamanho > 1 && !$identificador_ark);
|
||||
@ -176,8 +179,9 @@ function init() {
|
||||
|
||||
|
||||
$resultado['qrark'] = $qrark;
|
||||
$resultado['ark_full'] = $ark_full; // <-- use este no JS/analytics
|
||||
$resultado['tem_interrogacao'] = $tem_interrogacao;
|
||||
$resultado['ark_full'] = $ark_full; // <-- use este no JS/analytics
|
||||
$resultado['tem_interrogacao'] = $tem_interrogacao;
|
||||
$resultado['consulta_original_encontrada'] = $consulta_original_encontrada;
|
||||
|
||||
|
||||
return $resultado;
|
||||
@ -198,6 +202,8 @@ $qrark = $conteudo["qrark"];
|
||||
|
||||
$tem_interrogacao = $conteudo['tem_interrogacao'];
|
||||
|
||||
$consulta_original_encontrada = $conteudo['consulta_original_encontrada'];
|
||||
|
||||
function slug_titulo($s) {
|
||||
$s = trim((string)$s);
|
||||
if ($s === '') return '';
|
||||
@ -263,6 +269,7 @@ background: linear-gradient(to right, #FFC371, #FF5F6D); /* W3C, IE 10+/ Edge, F
|
||||
const arkFull = <?= json_encode($arkFull) ?>; // "68745/eM8Rf/gJ.ht"
|
||||
const qrark = <?= json_encode($qrark) ?>; // boolean
|
||||
const consultaMetadados = <?= json_encode($tem_interrogacao) ?>; // boolean
|
||||
const consulta_original_encontrada = <?= json_encode($consulta_original_encontrada) ?>;
|
||||
const tituloSlug = <?= json_encode($tituloSlug) ?>; // "o-titulo-do-livro"
|
||||
|
||||
const spinner = document.getElementById('spinner');
|
||||
@ -282,6 +289,7 @@ background: linear-gradient(to right, #FFC371, #FF5F6D); /* W3C, IE 10+/ Edge, F
|
||||
|
||||
if (ok) {
|
||||
const parts = [];
|
||||
if (!consulta_original_encontrada) parts.push('404');
|
||||
if (qrark) parts.push('qrcodeLivro');
|
||||
if (consultaMetadados) parts.push('meta');
|
||||
if (tituloSlug) parts.push(tituloSlug);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user