289 lines
17 KiB
PHP
289 lines
17 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="doc.php" class="btn btn-sm btn-outline-primary">Documentation</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; ?>
|
|
|
|
<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-warning" class="alert alert-warning mb-4 d-none">
|
|
<strong>Mode lent activé</strong>
|
|
<p>Le mode lent ajoute des délais supplémentaires entre les requêtes et réduit le nombre de favoris traités simultanément. Cela rend l'importation beaucoup plus lente mais réduit considérablement le risque de blocage par l'API.</p>
|
|
<p class="mb-0">Recommandé si vous rencontrez des erreurs de limite de taux (rate limit) ou si votre instance Misskey est très stricte sur le nombre de requêtes autorisées.</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>
|