permet de faire tourner différents jetons d'accès pour outrepasser les limitations vraiment beaucoup trop stricts de certaines api
325 lines
20 KiB
PHP
325 lines
20 KiB
PHP
<?php
|
|
/**
|
|
* FavMasToKey - Page d'accueil
|
|
*/
|
|
|
|
// Définir la constante pour inclure les fichiers
|
|
define('FAVMASTOKEY', true);
|
|
|
|
// Inclure les fichiers requis
|
|
require_once 'includes/config.php';
|
|
require_once 'includes/functions.php';
|
|
|
|
// Vérifier si l'utilisateur est authentifié
|
|
$is_authenticated = isset($_SESSION['misskey_token']) && !empty($_SESSION['misskey_token']);
|
|
$instance = isset($_SESSION['misskey_instance']) ? $_SESSION['misskey_instance'] : '';
|
|
|
|
// Traiter le formulaire de connexion Misskey
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'connect_token') {
|
|
if (isset($_POST['misskey_instance']) && isset($_POST['misskey_token'])) {
|
|
$instance = trim($_POST['misskey_instance']);
|
|
$token = trim($_POST['misskey_token']);
|
|
|
|
// Vérifier que l'instance et le token sont valides
|
|
if (empty($instance) || empty($token)) {
|
|
$_SESSION['messages'][] = [
|
|
'type' => 'danger',
|
|
'text' => 'Veuillez renseigner à la fois l\'instance Misskey et le jeton d\'accès.'
|
|
];
|
|
} else {
|
|
// Valider le format de l'instance
|
|
$instance = preg_replace('/^https?:\/\//', '', $instance);
|
|
$instance = rtrim($instance, '/');
|
|
|
|
if (!preg_match('/^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/', $instance)) {
|
|
$_SESSION['messages'][] = [
|
|
'type' => 'danger',
|
|
'text' => 'L\'URL de l\'instance Misskey semble invalide.'
|
|
];
|
|
} else {
|
|
// Vérifier la validité du token en effectuant une requête test
|
|
$validate_result = validate_misskey_token($instance, $token);
|
|
|
|
if ($validate_result['success']) {
|
|
// Stocker le token et l'instance dans la session
|
|
$_SESSION['misskey_token'] = $token;
|
|
$_SESSION['misskey_instance'] = $instance;
|
|
|
|
$_SESSION['messages'][] = [
|
|
'type' => 'success',
|
|
'text' => 'Connecté avec succès à ' . $instance . '.'
|
|
];
|
|
|
|
// Rediriger vers l'étape 3
|
|
header('Location: index.php#step3');
|
|
exit;
|
|
} else {
|
|
// Formater le message d'erreur correctement
|
|
$errorDetails = isset($validate_result['message']) ? $validate_result['message'] : 'Erreur inconnue';
|
|
// Si le message est un tableau, le convertir en chaîne JSON
|
|
if (is_array($errorDetails)) {
|
|
$errorDetails = json_encode($errorDetails, JSON_PRETTY_PRINT);
|
|
}
|
|
|
|
$_SESSION['messages'][] = [
|
|
'type' => 'danger',
|
|
'text' => 'Le jeton d\'accès semble invalide ou a expiré. Vérifiez que vous avez bien accordé la permission "i/favorites/create".',
|
|
'details' => $errorDetails
|
|
];
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$_SESSION['messages'][] = [
|
|
'type' => 'danger',
|
|
'text' => 'Données manquantes.'
|
|
];
|
|
}
|
|
}
|
|
|
|
// Traitement de la déconnexion
|
|
if (isset($_GET['action']) && $_GET['action'] === 'logout') {
|
|
// Supprimer les informations d'authentification
|
|
unset($_SESSION['misskey_token']);
|
|
unset($_SESSION['misskey_instance']);
|
|
|
|
$_SESSION['messages'][] = [
|
|
'type' => 'info',
|
|
'text' => 'Vous avez été déconnecté.'
|
|
];
|
|
|
|
// Rediriger vers la page d'accueil
|
|
header('Location: index.php');
|
|
exit;
|
|
}
|
|
|
|
// Initialiser les messages
|
|
$messages = [];
|
|
if (isset($_SESSION['messages'])) {
|
|
$messages = $_SESSION['messages'];
|
|
unset($_SESSION['messages']);
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="fr" data-bs-theme="dark">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="theme-color" content="#7e57c2">
|
|
<link rel="icon" href="images/favicon.svg" type="image/svg+xml">
|
|
<meta name="description" content="FavMasToKey - Transférez vos favoris de Mastodon vers Misskey en quelques clics">
|
|
<title>FavMasToKey - Transférer vos favoris de Mastodon vers Misskey</title>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
|
|
<link rel="stylesheet" href="css/styles.css">
|
|
</head>
|
|
<body>
|
|
<div class="container py-5">
|
|
<header class="text-center mb-5">
|
|
<h1>FavMasToKey</h1>
|
|
<p class="lead">Transférez vos favoris Mastodon vers Misskey en quelques clics</p>
|
|
<p><a href="diagnostic.php" class="btn btn-sm btn-outline-primary">Diagnostic</a> <a href="doc.php" class="btn btn-sm btn-outline-primary">Documentation</a> <a href="multitokens.php" class="btn btn-sm btn-outline-primary">Mode Filou</a></p>
|
|
</header>
|
|
|
|
<!-- Messages d'alerte -->
|
|
<?php if (!empty($messages)): ?>
|
|
<?php foreach ($messages as $message): ?>
|
|
<div class="alert alert-<?php echo $message['type']; ?> alert-dismissible fade show" role="alert">
|
|
<?php echo $message['text']; ?>
|
|
<?php if (isset($message['details']) && ENVIRONMENT === 'development'): ?>
|
|
<hr>
|
|
<details>
|
|
<summary>Détails techniques (mode développement)</summary>
|
|
<pre class="mt-2 p-2 bg-dark text-light"><?php echo htmlspecialchars($message['details']); ?></pre>
|
|
</details>
|
|
<?php endif; ?>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Fermer"></button>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-8">
|
|
<div class="card shadow-sm">
|
|
<div class="card-body">
|
|
<div class="steps">
|
|
<!-- Étape 1: Téléchargement du fichier JSON -->
|
|
<div class="step" id="step1">
|
|
<h3 class="card-title">1. Importer vos favoris Mastodon</h3>
|
|
<p>Téléchargez d'abord votre fichier d'export de favoris depuis Mastodon.</p>
|
|
|
|
<div class="card bg-light mb-3">
|
|
<div class="card-body">
|
|
<h5>Comment obtenir mon fichier de favoris ?</h5>
|
|
<ol>
|
|
<li>Connectez-vous à votre compte Mastodon</li>
|
|
<li>Allez dans <strong>Préférences</strong> > <strong>Exporter et importer</strong></li>
|
|
<li>Dans la section <strong>Exporter</strong>, cliquez sur <strong>Demander vos favoris</strong></li>
|
|
<li>Une fois le fichier prêt, téléchargez-le</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
|
|
<form id="upload-form" class="mt-4">
|
|
<div class="mb-3">
|
|
<label for="json-file" class="form-label">Fichier JSON des favoris</label>
|
|
<input type="file" class="form-control" id="json-file" name="json_file" accept=".json" required>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary">Analyser le fichier</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Étape 2: Connexion à Misskey -->
|
|
<div class="step d-none" id="step2">
|
|
<h3 class="card-title">2. Connexion à Misskey</h3>
|
|
<p>Connectez-vous à votre compte Misskey pour y importer vos favoris.</p>
|
|
|
|
<div id="file-summary" class="alert alert-info mb-4"></div>
|
|
|
|
<div class="card bg-light mb-4">
|
|
<div class="card-body">
|
|
<h5>Comment obtenir un jeton d'accès Misskey ?</h5>
|
|
<ol>
|
|
<li>Connectez-vous à votre compte Misskey</li>
|
|
<li>Allez dans <strong>Paramètres</strong> > <strong>API</strong></li>
|
|
<li>Cliquez sur <strong>Générer un nouveau jeton d'accès</strong></li>
|
|
<li>Donnez un nom à votre jeton (ex: "FavMasToKey")</li>
|
|
<li>Accordez <strong>toutes</strong> les permissions suivantes :
|
|
<ul class="mt-2">
|
|
<li><code>Afficher les informations du compte</code></li>
|
|
<li><code>Afficher les favoris</code></li>
|
|
<li><code>Gérer les favoris</code></li>
|
|
</ul>
|
|
</li>
|
|
<li>Cliquez sur <strong>Générer</strong> et copiez le jeton</li>
|
|
</ol>
|
|
<div class="alert alert-info mt-2">
|
|
<strong>Conseil :</strong> Si vous continuez à rencontrer des erreurs de permission, essayez d'accorder des permissions supplémentaires. Les exigences peuvent varier légèrement selon les versions de Misskey.
|
|
</div>
|
|
<div class="alert alert-warning mt-2 mb-0">
|
|
<strong>Important :</strong> Conservez ce jeton en lieu sûr. FavMasToKey ne stocke pas votre jeton de manière permanente, mais uniquement dans votre session de navigation.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form id="misskey-form" method="post" class="mt-4">
|
|
<input type="hidden" name="action" value="connect_token">
|
|
<div class="mb-3">
|
|
<label for="misskey-instance" class="form-label">Instance Misskey</label>
|
|
<input type="text" class="form-control" id="misskey-instance" name="misskey_instance"
|
|
placeholder="misskey.io" required>
|
|
<div class="form-text">Entrez le nom de domaine de votre instance Misskey (ex: misskey.io)</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="misskey-token" class="form-label">Jeton d'accès</label>
|
|
<input type="password" class="form-control" id="misskey-token" name="misskey_token"
|
|
placeholder="Votre jeton d'accès Misskey" required>
|
|
<div class="form-text">Collez le jeton d'accès généré dans les paramètres de votre compte Misskey</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary">Se connecter à Misskey</button>
|
|
<button type="button" class="btn btn-link" id="back-to-step1">Retour</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Étape 3: Migration des favoris -->
|
|
<div class="step d-none" id="step3">
|
|
<h3 class="card-title">3. Migration des favoris</h3>
|
|
<p>Nous allons maintenant transférer vos favoris vers Misskey.</p>
|
|
|
|
<?php if ($is_authenticated): ?>
|
|
<div class="alert alert-success mb-4">
|
|
<strong>Connecté à <?php echo htmlspecialchars($instance); ?></strong>
|
|
<p class="mb-0">Vous êtes authentifié et prêt à importer vos favoris.</p>
|
|
<div class="mt-2">
|
|
<a href="index.php?action=logout" class="btn btn-sm btn-outline-dark">Se déconnecter</a>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Mode lent -->
|
|
<div class="form-check form-switch mb-3">
|
|
<input class="form-check-input" type="checkbox" id="slow-mode">
|
|
<label class="form-check-label" for="slow-mode">Mode lent</label>
|
|
<div class="form-text">Activez cette option pour les instances Misskey avec des limitations d'API strictes</div>
|
|
</div>
|
|
|
|
<div id="slow-mode-options" class="mb-4 d-none">
|
|
<label for="slow-mode-delay" class="form-label">Délai entre les requêtes : <span id="delay-value">30</span> secondes</label>
|
|
<input type="range" class="form-range" id="slow-mode-delay" min="10" max="60" step="5" value="30">
|
|
<div class="d-flex justify-content-between small text-muted">
|
|
<span>10s (plus rapide)</span>
|
|
<span>60s (plus lent)</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="slow-mode-warning" class="alert alert-warning mb-4 d-none">
|
|
<strong>Mode lent activé</strong>
|
|
<p>Ce mode ajoute des délais importants entre les requêtes (30 secondes par défaut) et ne traite qu'un seul favori à la fois. Cela rend l'importation plus lente mais permet d'éviter (dans une certaine mesure) le risque de blocage par l'API.</p>
|
|
<p class="mb-0">Recommandé si vous rencontrez systématiquement des erreurs de limite de taux (rate limit) ou si votre instance Misskey est extrêmement stricte sur le nombre de requêtes autorisées.</p>
|
|
</div>
|
|
|
|
<!-- Mode tortue -->
|
|
<div class="form-check form-switch mb-3">
|
|
<input class="form-check-input" type="checkbox" id="tortoise-mode">
|
|
<label class="form-check-label" for="tortoise-mode">Mode tortue</label>
|
|
<div class="form-text">Activez cette option pour les instances Misskey avec des limitations d'API extrêmement strictes</div>
|
|
</div>
|
|
|
|
<div id="tortoise-mode-options" class="mb-4 d-none">
|
|
<label for="tortoise-mode-delay" class="form-label">Délai entre les requêtes : <span id="tortoise-delay-value">120</span> secondes</label>
|
|
<input type="range" class="form-range" id="tortoise-mode-delay" min="60" max="300" step="30" value="120">
|
|
<div class="d-flex justify-content-between small text-muted">
|
|
<span>60s (plus rapide)</span>
|
|
<span>300s (5 min)</span>
|
|
</div>
|
|
<div class="form-check mt-2">
|
|
<input class="form-check-input" type="checkbox" id="auto-pause-enabled" checked>
|
|
<label class="form-check-label" for="auto-pause-enabled">Pauses automatiques après détection de rate limit</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="tortoise-mode-warning" class="alert alert-warning mb-4 d-none">
|
|
<strong>Mode tortue activé</strong>
|
|
<p>Ce mode utilise des délais extrêmement longs entre les requêtes (2-5 minutes par défaut) et effectue des pauses automatiques de 15 minutes lorsque des limitations d'API sont détectées.</p>
|
|
<p class="mb-0">Utilisez ce mode pour les instances Misskey avec des limites d'API très strictes. La migration sera <strong>extrêmement lente</strong> mais devrait pouvoir terminer sans interventions manuelles fréquentes.</p>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="form-label">Progression globale</label>
|
|
<div class="progress" style="height: 20px;">
|
|
<div id="global-progress" class="progress-bar" role="progressbar"
|
|
style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="form-label">Opération en cours</label>
|
|
<div class="progress">
|
|
<div id="current-progress" class="progress-bar bg-info" role="progressbar"
|
|
style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<h5>Journal des opérations</h5>
|
|
<div id="log-container" class="border p-3 bg-light" style="max-height: 200px; overflow-y: auto;">
|
|
<div id="operation-log"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between">
|
|
<button type="button" class="btn btn-primary" id="start-migration">Démarrer la migration</button>
|
|
<button type="button" class="btn btn-warning d-none" id="pause-migration">Pause</button>
|
|
<button type="button" class="btn btn-danger" id="cancel-migration">Annuler</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="js/app.js"></script>
|
|
</body>
|
|
</html>
|