mirror of
https://github.com/manualdousuario/marreta.git
synced 2025-04-25 16:09:10 +00:00
documentação e padronização
This commit is contained in:
parent
10a8aa43ec
commit
f9cefd9328
6 changed files with 85 additions and 61 deletions
|
@ -91,9 +91,13 @@ A opção de `DEBUG` quando `true` não irá gerar cache!
|
|||
|
||||
## ⚙️ Personalizando
|
||||
|
||||
No `Rules.php` você pode configurar regras diferentes pra cada site e regras globais
|
||||
As configurações estão organizadas em `data/`:
|
||||
|
||||
Em `config.php` você tem a lista os sites que não quer permitir ou não permitem extrair dados e configurações de User Agents
|
||||
- `domain_rules.php`: Regras específicas para cada site
|
||||
- `global_rules.php`: Regras que se aplicam a todos os sites
|
||||
- `blocked_domains.php`: Lista de sites bloqueados
|
||||
- `user_agents.php`: Configurações de User Agents
|
||||
- `messages.php`: Mensagens do sistema
|
||||
|
||||
## 🛠️ Manutenção
|
||||
|
||||
|
|
21
app/api.php
21
app/api.php
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* API para análise de URLs
|
||||
*
|
||||
|
@ -28,25 +29,26 @@ $prefix = '/api/';
|
|||
|
||||
if (strpos($path, $prefix) === 0) {
|
||||
$url = urldecode(substr($path, strlen($prefix)));
|
||||
|
||||
|
||||
/**
|
||||
* Função para enviar resposta JSON padronizada
|
||||
*
|
||||
* @param array $data Dados a serem enviados na resposta
|
||||
* @param int $statusCode Código de status HTTP
|
||||
*/
|
||||
function sendResponse($data, $statusCode = 200) {
|
||||
function sendResponse($data, $statusCode = 200)
|
||||
{
|
||||
http_response_code($statusCode);
|
||||
$response = [
|
||||
'status' => $statusCode
|
||||
];
|
||||
|
||||
|
||||
if (isset($data['error'])) {
|
||||
$response['error'] = $data['error'];
|
||||
} else if (isset($data['url'])) {
|
||||
$response['url'] = $data['url'];
|
||||
}
|
||||
|
||||
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
@ -64,21 +66,20 @@ if (strpos($path, $prefix) === 0) {
|
|||
try {
|
||||
// Instancia o analisador de URLs
|
||||
$analyzer = new URLAnalyzer();
|
||||
|
||||
|
||||
// Tenta analisar a URL fornecida
|
||||
$analyzer->analyze($url);
|
||||
|
||||
|
||||
// Se a análise for bem-sucedida, retorna a URL processada
|
||||
sendResponse([
|
||||
'url' => SITE_URL . '/p/' . $url
|
||||
], 200);
|
||||
|
||||
} catch (Exception $e) {
|
||||
// Tratamento de erros com mapeamento para códigos HTTP apropriados
|
||||
$message = $e->getMessage();
|
||||
$statusCode = 400;
|
||||
$errorCode = 'GENERIC_ERROR';
|
||||
|
||||
|
||||
// Mapeia a mensagem de erro para o código e status apropriados
|
||||
foreach (MESSAGES as $key => $value) {
|
||||
if (strpos($message, $value['message']) !== false) {
|
||||
|
@ -87,10 +88,10 @@ if (strpos($path, $prefix) === 0) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Adiciona header de erro para melhor tratamento no cliente
|
||||
header('X-Error-Message: ' . $message);
|
||||
|
||||
|
||||
sendResponse([
|
||||
'error' => [
|
||||
'code' => $errorCode,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Classe responsável pelo gerenciamento de cache do sistema
|
||||
*
|
||||
|
@ -9,7 +10,8 @@
|
|||
*
|
||||
* Quando o modo DEBUG está ativo, todas as operações de cache são desativadas.
|
||||
*/
|
||||
class Cache {
|
||||
class Cache
|
||||
{
|
||||
/**
|
||||
* @var string Diretório onde os arquivos de cache serão armazenados
|
||||
*/
|
||||
|
@ -20,7 +22,8 @@ class Cache {
|
|||
*
|
||||
* Inicializa o diretório de cache e cria-o se não existir
|
||||
*/
|
||||
public function __construct() {
|
||||
public function __construct()
|
||||
{
|
||||
$this->cacheDir = CACHE_DIR;
|
||||
if (!file_exists($this->cacheDir)) {
|
||||
mkdir($this->cacheDir, 0777, true);
|
||||
|
@ -33,7 +36,8 @@ class Cache {
|
|||
* @param string $url URL para qual será gerado o ID
|
||||
* @return string Hash SHA-256 da URL normalizada
|
||||
*/
|
||||
public function generateId($url) {
|
||||
public function generateId($url)
|
||||
{
|
||||
// Remove protocolo e www
|
||||
$url = preg_replace('#^https?://(www\.)?#', '', $url);
|
||||
// Gera ID único usando SHA-256
|
||||
|
@ -46,7 +50,8 @@ class Cache {
|
|||
* @param string $url URL a ser verificada
|
||||
* @return bool True se existir cache, False caso contrário
|
||||
*/
|
||||
public function exists($url) {
|
||||
public function exists($url)
|
||||
{
|
||||
// Se DEBUG está ativo, sempre retorna false
|
||||
if (DEBUG) {
|
||||
return false;
|
||||
|
@ -63,7 +68,8 @@ class Cache {
|
|||
* @param string $url URL do conteúdo a ser recuperado
|
||||
* @return string|null Conteúdo em cache ou null se não existir
|
||||
*/
|
||||
public function get($url) {
|
||||
public function get($url)
|
||||
{
|
||||
// Se DEBUG está ativo, sempre retorna null
|
||||
if (DEBUG) {
|
||||
return null;
|
||||
|
@ -74,13 +80,13 @@ class Cache {
|
|||
}
|
||||
$id = $this->generateId($url);
|
||||
$cachePath = $this->cacheDir . '/' . $id . '.gz';
|
||||
|
||||
|
||||
// Lê e descomprime o conteúdo
|
||||
$compressedContent = file_get_contents($cachePath);
|
||||
if ($compressedContent === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return gzdecode($compressedContent);
|
||||
}
|
||||
|
||||
|
@ -91,7 +97,8 @@ class Cache {
|
|||
* @param string $content Conteúdo a ser armazenado em cache
|
||||
* @return bool True se o cache foi salvo com sucesso, False caso contrário
|
||||
*/
|
||||
public function set($url, $content) {
|
||||
public function set($url, $content)
|
||||
{
|
||||
// Se DEBUG está ativo, não gera cache
|
||||
if (DEBUG) {
|
||||
return true;
|
||||
|
@ -99,13 +106,13 @@ class Cache {
|
|||
|
||||
$id = $this->generateId($url);
|
||||
$cachePath = $this->cacheDir . '/' . $id . '.gz';
|
||||
|
||||
|
||||
// Comprime o conteúdo usando gzip
|
||||
$compressedContent = gzencode($content, 3);
|
||||
if ($compressedContent === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return file_put_contents($cachePath, $compressedContent) !== false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Classe responsável pelo gerenciamento de regras de manipulação de conteúdo
|
||||
*
|
||||
|
@ -7,7 +8,8 @@
|
|||
* Inclui funcionalidades para remoção de paywalls, elementos específicos,
|
||||
* manipulação de cookies e execução de códigos customizados.
|
||||
*/
|
||||
class Rules {
|
||||
class Rules
|
||||
{
|
||||
/**
|
||||
* Array associativo contendo regras específicas para cada domínio
|
||||
*
|
||||
|
@ -37,7 +39,8 @@ class Rules {
|
|||
* @param string $domain Domínio completo
|
||||
* @return string Domínio base sem www
|
||||
*/
|
||||
private function getBaseDomain($domain) {
|
||||
private function getBaseDomain($domain)
|
||||
{
|
||||
return preg_replace('/^www\./', '', $domain);
|
||||
}
|
||||
|
||||
|
@ -47,19 +50,20 @@ class Rules {
|
|||
* @param string $domain Domínio a ser dividido
|
||||
* @return array Array com todas as combinações possíveis do domínio
|
||||
*/
|
||||
private function getDomainParts($domain) {
|
||||
private function getDomainParts($domain)
|
||||
{
|
||||
$domain = $this->getBaseDomain($domain);
|
||||
$parts = explode('.', $domain);
|
||||
|
||||
|
||||
$combinations = [];
|
||||
for ($i = 0; $i < count($parts) - 1; $i++) {
|
||||
$combinations[] = implode('.', array_slice($parts, $i));
|
||||
}
|
||||
|
||||
usort($combinations, function($a, $b) {
|
||||
|
||||
usort($combinations, function ($a, $b) {
|
||||
return strlen($b) - strlen($a);
|
||||
});
|
||||
|
||||
|
||||
return $combinations;
|
||||
}
|
||||
|
||||
|
@ -69,15 +73,16 @@ class Rules {
|
|||
* @param string $domain Domínio para buscar regras
|
||||
* @return array|null Array com regras mescladas ou null se não encontrar
|
||||
*/
|
||||
public function getDomainRules($domain) {
|
||||
public function getDomainRules($domain)
|
||||
{
|
||||
$domainParts = $this->getDomainParts($domain);
|
||||
|
||||
|
||||
foreach ($this->domainRules as $pattern => $rules) {
|
||||
if ($this->getBaseDomain($domain) === $this->getBaseDomain($pattern)) {
|
||||
return $this->mergeWithGlobalRules($rules);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ($domainParts as $part) {
|
||||
foreach ($this->domainRules as $pattern => $rules) {
|
||||
if ($part === $this->getBaseDomain($pattern)) {
|
||||
|
@ -85,7 +90,7 @@ class Rules {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -95,7 +100,8 @@ class Rules {
|
|||
* @param array $rules Regras específicas do domínio
|
||||
* @return array Regras mescladas
|
||||
*/
|
||||
private function mergeWithGlobalRules($rules) {
|
||||
private function mergeWithGlobalRules($rules)
|
||||
{
|
||||
$globalRules = $this->getGlobalRules();
|
||||
|
||||
if (isset($rules['excludeGlobalRules']) && is_array($rules['excludeGlobalRules'])) {
|
||||
|
@ -130,7 +136,8 @@ class Rules {
|
|||
*
|
||||
* @return array Array com todas as regras globais
|
||||
*/
|
||||
public function getGlobalRules() {
|
||||
public function getGlobalRules()
|
||||
{
|
||||
return $this->globalRules;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Página principal do sistema
|
||||
*
|
||||
|
@ -38,6 +39,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {
|
|||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
@ -50,6 +52,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {
|
|||
<meta property="og:image" content="<?php echo SITE_URL; ?>/assets/opengraph.png" />
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
|
||||
<body class="bg-gray-50 min-h-screen">
|
||||
<div class="container mx-auto px-4 py-8 max-w-4xl">
|
||||
<!-- Cabeçalho da página -->
|
||||
|
@ -75,18 +78,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {
|
|||
<span class="inline-flex items-center px-5 rounded-l-lg border border-r-0 border-gray-300 bg-gray-50 text-gray-500">
|
||||
<img src="assets/svg/link.svg" class="w-6 h-6" alt="Link">
|
||||
</span>
|
||||
<input type="url"
|
||||
name="url"
|
||||
id="url"
|
||||
class="flex-1 block w-full rounded-none rounded-r-lg text-lg py-4 border border-l-0 border-gray-300 bg-gray-50 focus:border-blue-500 focus:ring-blue-500 shadow-sm bg-gray-50"
|
||||
placeholder="Digite a URL (ex: https://exemplo.com)"
|
||||
value="<?php echo htmlspecialchars($url); ?>"
|
||||
required
|
||||
pattern="https?://.+"
|
||||
title="Por favor, insira uma URL válida começando com http:// ou https://">
|
||||
<input type="url"
|
||||
name="url"
|
||||
id="url"
|
||||
class="flex-1 block w-full rounded-none rounded-r-lg text-lg py-4 border border-l-0 border-gray-300 bg-gray-50 focus:border-blue-500 focus:ring-blue-500 shadow-sm bg-gray-50"
|
||||
placeholder="Digite a URL (ex: https://exemplo.com)"
|
||||
value="<?php echo htmlspecialchars($url); ?>"
|
||||
required
|
||||
pattern="https?://.+"
|
||||
title="Por favor, insira uma URL válida começando com http:// ou https://">
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="mt-4 w-full inline-flex justify-center items-center px-6 py-4 border border-transparent text-lg font-medium rounded-lg text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200">
|
||||
<button type="submit"
|
||||
class="mt-4 w-full inline-flex justify-center items-center px-6 py-4 border border-transparent text-lg font-medium rounded-lg text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200">
|
||||
<img src="assets/svg/search.svg" class="w-6 h-6 mr-3" alt="Search">
|
||||
Analisar
|
||||
</button>
|
||||
|
@ -113,13 +116,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {
|
|||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Exemplo de uso direto -->
|
||||
<div class="mt-8 text-center text-base text-gray-500">
|
||||
<p>
|
||||
<img src="assets/svg/code.svg" class="inline-block w-5 h-5 mr-2" alt="Acesso direito">
|
||||
Acesso direto:
|
||||
<pre class="bg-gray-100 p-3 rounded-lg text-sm overflow-x-auto"><?php echo SITE_URL; ?>/p/https://exemplo.com</pre>
|
||||
Acesso direto:
|
||||
<pre class="bg-gray-100 p-3 rounded-lg text-sm overflow-x-auto"><?php echo SITE_URL; ?>/p/https://exemplo.com</pre>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -134,9 +137,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {
|
|||
Arraste o botão abaixo para sua barra de favoritos para acessar o <?php echo SITE_NAME; ?> rapidamente em qualquer página:
|
||||
</p>
|
||||
<div class="flex justify-center">
|
||||
<a href="javascript:(function(){let currentUrl=window.location.href;window.location.href='<?php echo SITE_URL; ?>/p/'+encodeURIComponent(currentUrl);})()"
|
||||
class="inline-flex items-center px-6 py-3 border-2 border-blue-500 font-medium rounded-lg text-blue-600 bg-white hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200 cursor-move"
|
||||
onclick="return false;">
|
||||
<a href="javascript:(function(){let currentUrl=window.location.href;window.location.href='<?php echo SITE_URL; ?>/p/'+encodeURIComponent(currentUrl);})()"
|
||||
class="inline-flex items-center px-6 py-3 border-2 border-blue-500 font-medium rounded-lg text-blue-600 bg-white hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200 cursor-move"
|
||||
onclick="return false;">
|
||||
<img src="assets/svg/marreta.svg" class="w-5 h-5 mr-2" alt="Marreta">
|
||||
Abrir no <?php echo SITE_NAME; ?>
|
||||
</a>
|
||||
|
@ -151,15 +154,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {
|
|||
Serviços alternativos
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<a href="https://archive.today" target="_blank"
|
||||
class="flex items-center p-4 rounded-lg border-2 border-gray-200 hover:border-blue-500 hover:bg-blue-50 transition-all duration-200">
|
||||
<a href="https://archive.today" target="_blank"
|
||||
class="flex items-center p-4 rounded-lg border-2 border-gray-200 hover:border-blue-500 hover:bg-blue-50 transition-all duration-200">
|
||||
<img src="assets/svg/archive.svg" class="w-8 h-8 mr-4" alt="Archive.today">
|
||||
<div>
|
||||
<div class="font-medium text-lg text-gray-800">archive.today</div>
|
||||
</div>
|
||||
</a>
|
||||
<a href="https://12ft.io" target="_blank"
|
||||
class="flex items-center p-4 rounded-lg border-2 border-gray-200 hover:border-green-500 hover:bg-green-50 transition-all duration-200">
|
||||
class="flex items-center p-4 rounded-lg border-2 border-gray-200 hover:border-green-500 hover:bg-green-50 transition-all duration-200">
|
||||
<img src="assets/svg/bypass.svg" class="w-8 h-8 mr-4" alt="12ft.io">
|
||||
<div>
|
||||
<div class="font-medium text-lg text-gray-800">12ft.io</div>
|
||||
|
@ -204,11 +207,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {
|
|||
</div>
|
||||
<h2 class="text-xl font-semibold text-gray-800 mt-6 mb-6 flex items-center">
|
||||
<img src="assets/svg/code.svg" class="w-6 h-6 mr-3" alt="Open Source">
|
||||
Projeto Open Source
|
||||
Projeto Open Source
|
||||
</h2>
|
||||
<div>
|
||||
<p class="text-gray-600">
|
||||
Este é um projeto de <a href="https://github.com/manualdousuario/marreta/" class="underline" target="_blank">código aberto</a> feito com ❤️!<br/>
|
||||
Este é um projeto de <a href="https://github.com/manualdousuario/marreta/" class="underline" target="_blank">código aberto</a> feito com ❤️!<br />
|
||||
Você pode contribuir, reportar problemas ou fazer sugestões através do <a href="https://github.com/manualdousuario/marreta/" class="underline" target="_blank">GitHub</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -218,4 +221,5 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {
|
|||
<!-- Scripts JavaScript -->
|
||||
<script src="assets/js/scripts.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Processador de URLs
|
||||
*
|
||||
|
@ -22,7 +23,7 @@ $prefix = '/p/';
|
|||
if (strpos($path, $prefix) === 0) {
|
||||
// Remove o prefixo e decodifica a URL
|
||||
$url = urldecode(substr($path, strlen($prefix)));
|
||||
|
||||
|
||||
// Valida o formato da URL
|
||||
if (filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
$analyzer = new URLAnalyzer();
|
||||
|
@ -35,7 +36,7 @@ if (strpos($path, $prefix) === 0) {
|
|||
} catch (Exception $e) {
|
||||
$errorMessage = $e->getMessage();
|
||||
$errorType = 'GENERIC_ERROR'; // Tipo padrão de erro
|
||||
|
||||
|
||||
// Mapeia a mensagem de erro para um tipo específico
|
||||
if (strpos($errorMessage, 'bloqueado') !== false) {
|
||||
$errorType = 'BLOCKED_DOMAIN';
|
||||
|
@ -48,7 +49,7 @@ if (strpos($path, $prefix) === 0) {
|
|||
} elseif (strpos($errorMessage, 'obter conteúdo') !== false) {
|
||||
$errorType = 'CONTENT_ERROR';
|
||||
}
|
||||
|
||||
|
||||
// Redireciona para a página inicial com mensagem de erro
|
||||
header('Location: /?message=' . $errorType);
|
||||
exit;
|
||||
|
|
Loading…
Add table
Reference in a new issue