permet de faire tourner différents jetons d'accès pour outrepasser les limitations vraiment beaucoup trop stricts de certaines api
308 lines
12 KiB
PHP
308 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* FavMasToKey - Traitement des favoris (version multi-tokens)
|
|
*/
|
|
|
|
// Définir la constante pour inclure les fichiers
|
|
define('FAVMASTOKEY', true);
|
|
|
|
// Forcer les en-têtes JSON dès le début pour éviter tout conflit
|
|
header('Content-Type: application/json');
|
|
|
|
// Activer la capture d'erreurs
|
|
set_error_handler(function($errno, $errstr, $errfile, $errline) {
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => "Erreur PHP: $errstr (ligne $errline dans $errfile)",
|
|
]);
|
|
exit;
|
|
});
|
|
|
|
try {
|
|
// Inclure les fichiers requis
|
|
require_once 'includes/config.php';
|
|
require_once 'includes/functions.php';
|
|
|
|
// Vérifier que la requête est en POST
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
|
|
exit;
|
|
}
|
|
|
|
// Récupérer les données envoyées
|
|
$input_data = file_get_contents('php://input');
|
|
$input = json_decode($input_data, true);
|
|
|
|
if (!$input || !isset($input['url'])) {
|
|
http_response_code(400);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Données invalides',
|
|
'debug' => [
|
|
'received' => $input_data ? substr($input_data, 0, 200) . '...' : 'Aucune donnée reçue'
|
|
]
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
// Récupérer l'instance Misskey (devrait être la même pour tous les tokens)
|
|
$misskey_instance = isset($_SESSION['misskey_instance']) ? $_SESSION['misskey_instance'] : '';
|
|
if (empty($misskey_instance)) {
|
|
http_response_code(400);
|
|
echo json_encode(['success' => false, 'message' => 'Instance Misskey non définie']);
|
|
exit;
|
|
}
|
|
|
|
// Récupérer l'URL à traiter
|
|
$url = $input['url'];
|
|
|
|
// Récupérer l'ID du token à utiliser
|
|
$token_id = isset($input['token_id']) ? $input['token_id'] : 'primary';
|
|
|
|
// Récupérer le token d'accès selon l'ID fourni
|
|
if ($token_id === 'primary') {
|
|
// Utiliser le token principal
|
|
if (!isset($_SESSION['misskey_token']) || empty($_SESSION['misskey_token'])) {
|
|
http_response_code(401);
|
|
echo json_encode(['success' => false, 'message' => 'Token principal non disponible']);
|
|
exit;
|
|
}
|
|
$token = $_SESSION['misskey_token'];
|
|
} else {
|
|
// Utiliser un token supplémentaire
|
|
if (!isset($_SESSION['additional_tokens']) || !isset($_SESSION['additional_tokens'][$token_id])) {
|
|
http_response_code(401);
|
|
echo json_encode(['success' => false, 'message' => 'Token supplémentaire non trouvé: ' . $token_id]);
|
|
exit;
|
|
}
|
|
$token = $_SESSION['additional_tokens'][$token_id]['token'];
|
|
|
|
// Mettre à jour les statistiques d'utilisation du token
|
|
$_SESSION['additional_tokens'][$token_id]['last_used'] = time();
|
|
$_SESSION['additional_tokens'][$token_id]['usage_count'] =
|
|
(isset($_SESSION['additional_tokens'][$token_id]['usage_count']) ?
|
|
$_SESSION['additional_tokens'][$token_id]['usage_count'] : 0) + 1;
|
|
}
|
|
|
|
// Journaliser le début du traitement
|
|
error_log("Traitement de l'URL: " . $url . " avec token ID: " . $token_id);
|
|
|
|
// Traitement de l'URL
|
|
// 1. Vérifier si nous avons un ID en cache pour cette URL
|
|
$cachedMisskeyId = null;
|
|
$federatedCache = get_federated_cache();
|
|
|
|
if (isset($federatedCache[$url])) {
|
|
$cachedMisskeyId = $federatedCache[$url]['id'];
|
|
error_log("ID trouvé en cache pour $url: $cachedMisskeyId");
|
|
}
|
|
|
|
// 2. Recherche de la note sur le réseau fédéré
|
|
$noteId = null;
|
|
$searchNeeded = true;
|
|
|
|
if ($cachedMisskeyId) {
|
|
$noteId = $cachedMisskeyId;
|
|
$searchNeeded = false;
|
|
error_log("Utilisation de l'ID en cache, recherche fédérée évitée pour: $url");
|
|
}
|
|
|
|
if ($searchNeeded) {
|
|
$searchResult = search_federated_note($misskey_instance, $url, $token);
|
|
|
|
if ($searchResult['success'] && isset($searchResult['data']) && !empty($searchResult['data'])) {
|
|
if (isset($searchResult['data']['id']) && !empty($searchResult['data']['id'])) {
|
|
$noteId = $searchResult['data']['id'];
|
|
|
|
// Sauvegarder dans le cache
|
|
update_federated_cache($url, $noteId);
|
|
|
|
error_log("Note trouvée et mise en cache: $url -> $noteId");
|
|
} else {
|
|
// L'ID est manquant dans la réponse
|
|
$dataKeys = is_array($searchResult['data']) ? array_keys($searchResult['data']) : ['non_array'];
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'result' => [
|
|
'status' => 'error',
|
|
'message' => "Note trouvée mais sans ID valide: $url",
|
|
'error_type' => 'invalid_response',
|
|
'details' => "Clés disponibles: " . implode(', ', $dataKeys)
|
|
]
|
|
]);
|
|
exit;
|
|
}
|
|
} else {
|
|
// Note non trouvée ou erreur de recherche
|
|
$errorMessage = isset($searchResult['message']) ? $searchResult['message'] : "Publication introuvable";
|
|
$errorCode = isset($searchResult['error_code']) ? $searchResult['error_code'] : '';
|
|
$httpCode = isset($searchResult['http_code']) ? $searchResult['http_code'] : '';
|
|
|
|
// Déterminer le type d'erreur
|
|
$errorType = 'not_found';
|
|
if (strpos($errorMessage, 'rate limit') !== false || $httpCode == 429 ||
|
|
(isset($searchResult['data']['error']) &&
|
|
isset($searchResult['data']['error']['code']) && $searchResult['data']['error']['code'] == 'RATE_LIMIT_EXCEEDED')) {
|
|
$errorType = 'rate_limit';
|
|
$errorMessage = "Limite d'API atteinte. Ce jeton doit se reposer.";
|
|
} elseif ($httpCode >= 500) {
|
|
$errorType = 'server_error';
|
|
$errorMessage = "L'instance Misskey rencontre des problèmes. Statut HTTP: $httpCode";
|
|
} elseif ($httpCode == 401 || $httpCode == 403) {
|
|
$errorType = 'auth_error';
|
|
$errorMessage = "Problème d'authentification ou de permission avec ce jeton.";
|
|
} elseif ($httpCode == 0) {
|
|
$errorType = 'network_error';
|
|
$errorMessage = "Problème de connexion réseau. Vérifiez votre connectivité.";
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'result' => [
|
|
'status' => $errorType == 'rate_limit' ? 'warning' : 'error',
|
|
'message' => "Publication non trouvée sur le réseau fédéré: $url ($errorMessage)",
|
|
'error_type' => $errorType,
|
|
'details' => $httpCode ? "HTTP: $httpCode" : ""
|
|
]
|
|
]);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// 3. Vérifier si la note est déjà favorite
|
|
$favoriteCheckResult = check_if_favorited($misskey_instance, $noteId, $token);
|
|
|
|
if ($favoriteCheckResult['success'] && $favoriteCheckResult['is_favorited']) {
|
|
// La note est déjà dans les favoris
|
|
echo json_encode([
|
|
'success' => true,
|
|
'result' => [
|
|
'status' => 'info',
|
|
'message' => "Déjà dans vos favoris: $url",
|
|
'error_type' => 'already_favorited',
|
|
'misskey_id' => $noteId
|
|
]
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
// 4. Ajouter la note aux favoris
|
|
$favoriteResult = add_to_favorites($misskey_instance, $noteId, $token);
|
|
|
|
if ($favoriteResult['success']) {
|
|
echo json_encode([
|
|
'success' => true,
|
|
'result' => [
|
|
'status' => 'success',
|
|
'message' => "Ajouté aux favoris: $url",
|
|
'misskey_id' => $noteId
|
|
]
|
|
]);
|
|
} else {
|
|
// Déterminer le type d'erreur
|
|
$errorMessage = isset($favoriteResult['data']['error']['message'])
|
|
? $favoriteResult['data']['error']['message']
|
|
: (isset($favoriteResult['message']) ? $favoriteResult['message'] : 'Erreur inconnue');
|
|
|
|
// Extraire le code d'erreur si disponible
|
|
$errorCode = isset($favoriteResult['data']['error']['code'])
|
|
? $favoriteResult['data']['error']['code']
|
|
: '';
|
|
|
|
// Déterminer le type d'erreur
|
|
$errorType = 'api_error';
|
|
if (strpos($errorMessage, 'already') !== false) {
|
|
$errorType = 'already_favorited';
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'result' => [
|
|
'status' => 'info',
|
|
'message' => "Déjà dans vos favoris: $url",
|
|
'error_type' => $errorType,
|
|
'misskey_id' => $noteId
|
|
]
|
|
]);
|
|
exit;
|
|
} elseif (strpos($errorMessage, 'rate limit') !== false || strpos($errorMessage, 'limit exceeded') !== false || $errorCode == 'RATE_LIMIT_EXCEEDED') {
|
|
$errorType = 'rate_limit';
|
|
$message = "Limite d'API atteinte pour: $url. Ce jeton doit se reposer.";
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'result' => [
|
|
'status' => 'warning',
|
|
'message' => $message,
|
|
'error_type' => $errorType,
|
|
'details' => $errorMessage,
|
|
'misskey_id' => $noteId
|
|
]
|
|
]);
|
|
exit;
|
|
} elseif (strpos($errorMessage, 'permission') !== false || $errorCode == 'NO_PERMISSION') {
|
|
$errorType = 'permission_denied';
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'result' => [
|
|
'status' => 'error',
|
|
'message' => "Erreur lors de l'ajout aux favoris: $errorMessage",
|
|
'error_type' => $errorType,
|
|
'details' => $errorCode ? "Code: $errorCode" : "",
|
|
'misskey_id' => $noteId
|
|
]
|
|
]);
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
// Capturer toutes les exceptions et renvoyer un message d'erreur formaté en JSON
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Exception: ' . $e->getMessage(),
|
|
'file' => $e->getFile(),
|
|
'line' => $e->getLine()
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Récupère le cache de fédération depuis la session
|
|
*
|
|
* @return array Cache de fédération
|
|
*/
|
|
function get_federated_cache() {
|
|
if (!isset($_SESSION['federated_cache'])) {
|
|
$_SESSION['federated_cache'] = [];
|
|
}
|
|
|
|
return $_SESSION['federated_cache'];
|
|
}
|
|
|
|
/**
|
|
* Met à jour le cache de fédération dans la session
|
|
*
|
|
* @param string $url URL de la publication Mastodon
|
|
* @param string $misskey_id ID de la publication sur Misskey
|
|
*/
|
|
function update_federated_cache($url, $misskey_id) {
|
|
if (!isset($_SESSION['federated_cache'])) {
|
|
$_SESSION['federated_cache'] = [];
|
|
}
|
|
|
|
$_SESSION['federated_cache'][$url] = [
|
|
'id' => $misskey_id,
|
|
'timestamp' => time()
|
|
];
|
|
|
|
// Nettoyer le cache si nécessaire (plus de 1000 entrées)
|
|
if (count($_SESSION['federated_cache']) > 1000) {
|
|
// Trier par timestamp et ne garder que les 500 plus récentes
|
|
uasort($_SESSION['federated_cache'], function($a, $b) {
|
|
return $b['timestamp'] - $a['timestamp'];
|
|
});
|
|
|
|
$_SESSION['federated_cache'] = array_slice($_SESSION['federated_cache'], 0, 500, true);
|
|
}
|
|
} |