Files
wevads-platform/public/system-tools.php
2026-02-26 04:53:11 +01:00

542 lines
30 KiB
PHP

<?php
header('Content-Type: text/html; charset=UTF-8');
// Actions POST
if($_SERVER['REQUEST_METHOD']==='POST' && isset($_POST['action'])) {
header('Content-Type: application/json');
$action = $_POST['action'];
$tool = $_POST['tool'] ?? '';
switch($action) {
case 'check_all':
$results = [];
// PowerShell Modules
$psModules = ['AzureAD','Microsoft.Graph.Users','Microsoft.Graph.Identity.SignIns','Az.Accounts','Az.Resources','ExchangeOnlineManagement','MSOnline','Microsoft.Graph','Microsoft.Graph.Authentication'];
foreach($psModules as $mod) {
$out = trim(shell_exec("pwsh -Command \"if(Get-Module -ListAvailable -Name '$mod' -ErrorAction SilentlyContinue){echo 'YES'}\" 2>/dev/null"));
$results['pwsh'][$mod] = strpos($out, 'YES') !== false;
}
// System Tools
$sysTools = [
'pwsh' => 'which pwsh',
'python3' => 'which python3',
'pip3' => 'which pip3',
'google-chrome' => 'which google-chrome',
'chromium' => 'which chromium-browser',
'x11vnc' => 'which x11vnc',
'Xvfb' => 'which Xvfb',
'node' => 'which node',
'git' => 'which git',
'curl' => 'which curl',
'jq' => 'which jq',
'psql' => 'which psql',
'composer' => 'which composer',
'php' => 'which php'
];
foreach($sysTools as $name => $cmd) {
$results['system'][$name] = trim(shell_exec($cmd)) !== '';
}
// Python Packages
$pipPkgs = ['selenium','playwright','requests','beautifulsoup4','pandas','openpyxl','python-dotenv','cloudflare','dnspython','psycopg2-binary','paramiko','msal','O365'];
foreach($pipPkgs as $pkg) {
$out = shell_exec("pip3 show $pkg 2>/dev/null | grep -c Name");
$results['pip'][$pkg] = intval(trim($out)) > 0;
}
// Playwright browsers
$results['playwright']['chromium'] = file_exists(shell_exec('python3 -c "import playwright; print(playwright.__file__.replace(\"__init__.py\",\"\"))" 2>/dev/null').'driver/package/.local-browsers') ||
is_dir('/root/.cache/ms-playwright');
echo json_encode(['success'=>true,'results'=>$results]);
exit;
case 'install':
$output = '';
$success = false;
switch($tool) {
// PowerShell Modules
case 'AzureAD':
case 'Az.Accounts':
case 'Az.Resources':
case 'ExchangeOnlineManagement':
case 'MSOnline':
case 'Microsoft.Graph':
case 'Microsoft.Graph.Authentication':
$output = shell_exec("pwsh -Command \"Install-Module -Name $tool -Force -AllowClobber -Scope CurrentUser\" 2>&1");
$check = shell_exec("pwsh -Command \"Get-InstalledModule -Name '$tool' -ErrorAction SilentlyContinue\" 2>/dev/null");
$success = strpos($check, $tool) !== false;
break;
// System Tools
case 'jq':
$output = shell_exec("apt-get update && apt-get install -y jq 2>&1");
$success = trim(shell_exec('which jq')) !== '';
break;
case 'composer':
$output = shell_exec("curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer 2>&1");
$success = trim(shell_exec('which composer')) !== '';
break;
case 'node':
$output = shell_exec("curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs 2>&1");
$success = trim(shell_exec('which node')) !== '';
break;
// Python Packages
case 'selenium':
case 'playwright':
case 'requests':
case 'beautifulsoup4':
case 'pandas':
case 'openpyxl':
case 'python-dotenv':
case 'cloudflare':
case 'dnspython':
case 'psycopg2-binary':
case 'paramiko':
case 'msal':
case 'O365':
$output = shell_exec("pip3 install $tool --break-system-packages 2>&1");
$check = shell_exec("pip3 show $tool 2>/dev/null | grep -c Name");
$success = intval(trim($check)) > 0;
break;
// Playwright browsers
case 'playwright-browsers':
$output = shell_exec("playwright install chromium 2>&1");
$success = true;
break;
}
echo json_encode(['success'=>$success,'output'=>$output,'tool'=>$tool]);
exit;
case 'install_all_pwsh':
$modules = ['AzureAD','Az.Accounts','Az.Resources','ExchangeOnlineManagement','MSOnline','Microsoft.Graph'];
$output = '';
foreach($modules as $mod) {
$output .= "Installing $mod...\n";
$output .= shell_exec("pwsh -Command \"Install-Module -Name $mod -Force -AllowClobber -Scope CurrentUser\" 2>&1");
$output .= "\n";
}
echo json_encode(['success'=>true,'output'=>$output]);
exit;
case 'fix_all':
$output = shell_exec('/opt/wevads/scripts/fix-dependencies.sh --force 2>&1');
echo json_encode(['success'=>true,'output'=>$output]);
exit;
case 'install_all_pip':
$pkgs = ['selenium','playwright','requests','beautifulsoup4','pandas','openpyxl','python-dotenv','cloudflare','dnspython','psycopg2-binary','paramiko','msal','O365'];
$output = shell_exec("pip3 install " . implode(' ', $pkgs) . " --break-system-packages 2>&1");
echo json_encode(['success'=>true,'output'=>$output]);
exit;
}
exit;
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>System Tools - WEVAL</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root{--primary:#6366f1;--success:#22c55e;--warning:#f59e0b;--danger:#ef4444;--bg:#0f172a;--card:#1e293b;--border:#334155;--text:#e2e8f0}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Segoe UI',system-ui,sans-serif;background:var(--bg);color:var(--text);min-height:100vh}
.header{background:linear-gradient(135deg,#1e293b,#334155);padding:16px 24px;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(--border)}
.header h1{font-size:20px;display:flex;align-items:center;gap:12px}
.header h1 i{color:var(--primary)}
.header-actions{display:flex;gap:10px}
.btn{padding:10px 18px;border:none;border-radius:8px;cursor:pointer;font-size:13px;font-weight:600;display:flex;align-items:center;gap:8px;transition:all 0.2s}
.btn-primary{background:var(--primary);color:white}
.btn-success{background:var(--success);color:white}
.btn-warning{background:var(--warning);color:white}
.btn-danger{background:var(--danger);color:white}
.btn-sm{padding:6px 12px;font-size:11px}
.btn:hover{transform:scale(1.05);filter:brightness(1.1)}
.btn:disabled{opacity:0.5;cursor:not-allowed;transform:none}
.container{padding:24px;display:grid;grid-template-columns:repeat(auto-fit,minmax(400px,1fr));gap:20px}
.card{background:var(--card);border-radius:16px;border:1px solid var(--border);overflow:hidden}
.card-header{background:linear-gradient(135deg,#334155,#475569);padding:14px 18px;display:flex;justify-content:space-between;align-items:center}
.card-header h3{font-size:14px;display:flex;align-items:center;gap:10px}
.card-header h3 i{font-size:16px}
.card-body{padding:16px}
.tool-grid{display:flex;flex-direction:column;gap:8px}
.tool-item{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;background:#0f172a;border-radius:10px;border:1px solid var(--border)}
.tool-info{display:flex;align-items:center;gap:12px}
.tool-icon{width:36px;height:36px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:14px}
.tool-icon.pwsh{background:#012456;color:#3b82f6}
.tool-icon.python{background:#306998;color:#ffd43b}
.tool-icon.system{background:#334155;color:#94a3b8}
.tool-name{font-size:13px;font-weight:600}
.tool-status{display:flex;align-items:center;gap:8px}
.status-badge{padding:4px 10px;border-radius:6px;font-size:11px;font-weight:600}
.status-badge.installed{background:#166534;color:#86efac}
.status-badge.missing{background:#991b1b;color:#fca5a5}
.status-badge.checking{background:#854d0e;color:#fde047}
.install-btn{padding:6px 12px;background:var(--primary);color:white;border:none;border-radius:6px;font-size:11px;cursor:pointer;display:flex;align-items:center;gap:4px}
.install-btn:hover{background:#4f46e5}
.install-btn:disabled{opacity:0.5;cursor:not-allowed}
.console{background:#0f172a;border-radius:12px;padding:16px;margin-top:20px;font-family:'Fira Code',monospace;font-size:11px;max-height:300px;overflow-y:auto;border:1px solid var(--border)}
.console .line{margin-bottom:4px;line-height:1.6}
.console .time{color:#a78bfa}
.console .info{color:#60a5fa}
.console .success{color:#34d399}
.console .error{color:#f87171}
.console .warning{color:#fbbf24}
.summary{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px}
.summary-card{background:var(--card);border-radius:12px;padding:16px;text-align:center;border:1px solid var(--border)}
.summary-card h4{font-size:24px;margin-bottom:4px}
.summary-card p{font-size:11px;color:#94a3b8}
.summary-card.ok h4{color:var(--success)}
.summary-card.ko h4{color:var(--danger)}
.loading{display:inline-block;width:14px;height:14px;border:2px solid #ffffff40;border-radius:50%;border-top-color:#fff;animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
a.back-link{color:var(--primary);text-decoration:none;font-size:13px;display:flex;align-items:center;gap:6px}
a.back-link:hover{text-decoration:underline}
</style>
</head>
<body>
<div class="header">
<h1><i class="fa fa-toolbox"></i> System Tools & Dependencies</h1>
<button class="btn btn-sm btn-info" onclick="document.getElementById('systemHelpModal').style.display='flex'" style="margin-left:15px;">
<i class="fas fa-question-circle"></i> Aide
</button>
<div class="header-actions">
<a href="index.php" class="back-link"><i class="fa fa-arrow-left"></i> Retour</a>
<button class="btn btn-warning" onclick="fixAll()" style="margin-right:10px;"><i class="fas fa-wrench"></i> Réparer Tout</button>
<button class="btn btn-primary" onclick="checkAll()"><i class="fa fa-sync"></i> Vérifier Tout</button>
</div>
</div>
<div class="container">
<!-- SUMMARY -->
<div style="grid-column:1/-1">
<div class="summary">
<div class="summary-card" id="sum-total"><h4>—</h4><p>Total Outils</p></div>
<div class="summary-card ok" id="sum-ok"><h4>—</h4><p>Installés</p></div>
<div class="summary-card ko" id="sum-ko"><h4>—</h4><p>Manquants</p></div>
<div class="summary-card" id="sum-pct"><h4>—%</h4><p>Complet</p></div>
</div>
</div>
<!-- POWERSHELL MODULES -->
<div class="card">
<div class="card-header">
<h3><i class="fab fa-microsoft" style="color:#3b82f6"></i> PowerShell Modules</h3>
<button class="btn btn-sm btn-primary" onclick="installAllPwsh()"><i class="fa fa-download"></i> Tout Installer</button>
</div>
<div class="card-body">
<div class="tool-grid" id="pwsh-tools">
<div class="tool-item"><div class="tool-info"><div class="tool-icon pwsh"><i class="fa fa-spinner fa-spin"></i></div><span class="tool-name">Chargement...</span></div></div>
</div>
</div>
</div>
<!-- SYSTEM TOOLS -->
<div class="card">
<div class="card-header">
<h3><i class="fa fa-terminal" style="color:#94a3b8"></i> System Tools</h3>
</div>
<div class="card-body">
<div class="tool-grid" id="system-tools">
<div class="tool-item"><div class="tool-info"><div class="tool-icon system"><i class="fa fa-spinner fa-spin"></i></div><span class="tool-name">Chargement...</span></div></div>
</div>
</div>
</div>
<!-- PYTHON PACKAGES -->
<div class="card">
<div class="card-header">
<h3><i class="fab fa-python" style="color:#ffd43b"></i> Python Packages</h3>
<button class="btn btn-sm btn-primary" onclick="installAllPip()"><i class="fa fa-download"></i> Tout Installer</button>
</div>
<div class="card-body">
<div class="tool-grid" id="pip-tools">
<div class="tool-item"><div class="tool-info"><div class="tool-icon python"><i class="fa fa-spinner fa-spin"></i></div><span class="tool-name">Chargement...</span></div></div>
</div>
</div>
</div>
<!-- CONSOLE -->
<div class="card" style="grid-column:1/-1">
<div class="card-header">
<h3><i class="fa fa-terminal"></i> Console</h3>
<button class="btn btn-sm btn-danger" onclick="clearConsole()"><i class="fa fa-trash"></i> Clear</button>
</div>
<div class="card-body">
<div class="console" id="console">
<div class="line"><span class="time">[System]</span> <span class="info">Cliquez sur "Vérifier Tout" pour scanner les outils</span></div>
</div>
</div>
</div>
</div>
<script>
var toolsData = {};
function log(msg, type='info') {
var c = document.getElementById('console');
var t = new Date().toLocaleTimeString();
c.innerHTML += '<div class="line"><span class="time">[' + t + ']</span> <span class="' + type + '">' + msg + '</span></div>';
c.scrollTop = c.scrollHeight;
}
function clearConsole() {
document.getElementById('console').innerHTML = '<div class="line"><span class="time">[System]</span> <span class="info">Console cleared</span></div>';
}
function checkAll() {
log('🔍 Vérification de tous les outils...', 'warning');
['pwsh-tools','system-tools','pip-tools'].forEach(id => {
document.getElementById(id).innerHTML = '<div class="tool-item"><div class="tool-info"><div class="tool-icon"><i class="fa fa-spinner fa-spin"></i></div><span class="tool-name">Vérification...</span></div></div>';
});
fetch('', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'action=check_all'})
.then(r => r.json())
.then(d => {
if(d.success) {
toolsData = d.results;
renderTools();
updateSummary();
log('✅ Vérification terminée', 'success');
}
})
.catch(e => log('❌ Erreur: ' + e, 'error'));
}
function renderTools() {
// PowerShell
var html = '';
Object.keys(toolsData.pwsh || {}).forEach(name => {
var ok = toolsData.pwsh[name];
html += '<div class="tool-item">' +
'<div class="tool-info">' +
'<div class="tool-icon pwsh"><i class="fab fa-microsoft"></i></div>' +
'<span class="tool-name">' + name + '</span>' +
'</div>' +
'<div class="tool-status">' +
'<span class="status-badge ' + (ok ? 'installed' : 'missing') + '">' + (ok ? '✓ Installé' : '✗ Manquant') + '</span>' +
(ok ? '' : '<button class="install-btn" onclick="installTool(\'' + name + '\')"><i class="fa fa-download"></i></button>') +
'</div>' +
'</div>';
});
document.getElementById('pwsh-tools').innerHTML = html || '<div class="tool-item">Aucun</div>';
// System
html = '';
Object.keys(toolsData.system || {}).forEach(name => {
var ok = toolsData.system[name];
html += '<div class="tool-item">' +
'<div class="tool-info">' +
'<div class="tool-icon system"><i class="fa fa-cube"></i></div>' +
'<span class="tool-name">' + name + '</span>' +
'</div>' +
'<div class="tool-status">' +
'<span class="status-badge ' + (ok ? 'installed' : 'missing') + '">' + (ok ? '✓ OK' : '✗ Manquant') + '</span>' +
(ok ? '' : '<button class="install-btn" onclick="installTool(\'' + name + '\')"><i class="fa fa-download"></i></button>') +
'</div>' +
'</div>';
});
document.getElementById('system-tools').innerHTML = html || '<div class="tool-item">Aucun</div>';
// Pip
html = '';
Object.keys(toolsData.pip || {}).forEach(name => {
var ok = toolsData.pip[name];
html += '<div class="tool-item">' +
'<div class="tool-info">' +
'<div class="tool-icon python"><i class="fab fa-python"></i></div>' +
'<span class="tool-name">' + name + '</span>' +
'</div>' +
'<div class="tool-status">' +
'<span class="status-badge ' + (ok ? 'installed' : 'missing') + '">' + (ok ? '✓ Installé' : '✗ Manquant') + '</span>' +
(ok ? '' : '<button class="install-btn" onclick="installTool(\'' + name + '\')"><i class="fa fa-download"></i></button>') +
'</div>' +
'</div>';
});
document.getElementById('pip-tools').innerHTML = html || '<div class="tool-item">Aucun</div>';
}
function updateSummary() {
var total = 0, ok = 0;
['pwsh','system','pip'].forEach(cat => {
Object.values(toolsData[cat] || {}).forEach(v => {
total++;
if(v) ok++;
});
});
var ko = total - ok;
var pct = total > 0 ? Math.round((ok/total)*100) : 0;
document.getElementById('sum-total').querySelector('h4').textContent = total;
document.getElementById('sum-ok').querySelector('h4').textContent = ok;
document.getElementById('sum-ko').querySelector('h4').textContent = ko;
document.getElementById('sum-pct').querySelector('h4').textContent = pct + '%';
}
function installTool(name) {
log('📦 Installation de ' + name + '...', 'warning');
fetch('', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'action=install&tool=' + encodeURIComponent(name)})
.then(r => r.json())
.then(d => {
if(d.success) {
log('✅ ' + name + ' installé avec succès', 'success');
} else {
log('❌ Échec installation ' + name, 'error');
}
if(d.output) {
d.output.split('\n').slice(0,5).forEach(line => {
if(line.trim()) log(line, 'info');
});
}
setTimeout(checkAll, 1000);
})
.catch(e => log('❌ Erreur: ' + e, 'error'));
}
function installAllPwsh() {
log('📦 Installation de tous les modules PowerShell...', 'warning');
fetch('', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'action=install_all_pwsh'})
.then(r => r.json())
.then(d => {
log('✅ Modules PowerShell installés', 'success');
setTimeout(checkAll, 2000);
});
}
function installAllPip() {
log('📦 Installation de tous les packages Python...', 'warning');
fetch('', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'action=install_all_pip'})
.then(r => r.json())
.then(d => {
log('✅ Packages Python installés', 'success');
setTimeout(checkAll, 2000);
});
}
// Auto-check on load
setTimeout(checkAll, 500);
</script>
<!-- Modal Aide System Tools -->
<div id="systemHelpModal" style="display:none; position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.9); z-index:9999; overflow-y:auto;">
<div style="background:#1a1a2e; border-radius:12px; padding:30px; max-width:900px; margin:40px auto; border:1px solid #00d4ff;">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
<h4 style="color:#00d4ff; margin:0;"><i class="fas fa-info-circle"></i> System Tools & Dependencies - Guide</h4>
<button onclick="document.getElementById('systemHelpModal').style.display='none'" style="background:none; border:none; color:#fff; font-size:24px; cursor:pointer;">&times;</button>
</div>
<div style="color:#ccc; line-height:1.6; font-size:12px;">
<h5 style="color:#00d4ff; margin-bottom:15px;"><i class="fas fa-chart-bar"></i> Statistiques Header</h5>
<div style="display:flex; gap:10px; margin-bottom:20px; flex-wrap:wrap;">
<div style="background:#2d3748; padding:10px; border-radius:6px; flex:1; min-width:120px;">
<strong style="color:#fff;">Total Outils</strong><br>
<span style="font-size:11px;">Nombre total d outils configurés</span>
</div>
<div style="background:#2d3748; padding:10px; border-radius:6px; flex:1; min-width:120px;">
<strong style="color:#22c55e;">Installés</strong><br>
<span style="font-size:11px;">Outils détectés comme installés</span>
</div>
<div style="background:#2d3748; padding:10px; border-radius:6px; flex:1; min-width:120px;">
<strong style="color:#ef4444;">Manquants</strong><br>
<span style="font-size:11px;">Outils non installés</span>
</div>
<div style="background:#2d3748; padding:10px; border-radius:6px; flex:1; min-width:120px;">
<strong style="color:#00d4ff;">% Complet</strong><br>
<span style="font-size:11px;">Pourcentage de completion</span>
</div>
</div>
<h5 style="color:#6366f1; margin-bottom:15px;"><i class="fab fa-microsoft"></i> PowerShell Modules</h5>
<div style="background:#2d3748; padding:12px; border-radius:8px; margin-bottom:15px;">
<p style="margin-bottom:10px;">Modules PowerShell pour gérer Office 365, Azure AD et Exchange Online.</p>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:8px; font-size:11px;">
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#63b3ed;">AzureAD</strong> - Gestion Azure Active Directory</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#63b3ed;">Microsoft.Graph.Users</strong> - API Graph Users</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#63b3ed;">Az.Accounts</strong> - Authentification Azure</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#63b3ed;">Az.Resources</strong> - Ressources Azure</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#63b3ed;">ExchangeOnlineManagement</strong> - Gestion Exchange</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#63b3ed;">MSOnline</strong> - Microsoft Online Services</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#63b3ed;">Microsoft.Graph</strong> - SDK Graph complet</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#63b3ed;">Microsoft.Graph.Authentication</strong> - Auth Graph</div>
</div>
<div style="background:#1e293b; padding:6px; border-radius:4px; margin-top:8px; font-size:10px;">
<strong style="color:#00d4ff;">🖥️ Utilisé par:</strong> Steps 2-6, 10-12 du Workflow (check MFA, change password, Azure App, Exchange config)
</div>
</div>
<h5 style="color:#f59e0b; margin-bottom:15px;"><i class="fas fa-terminal"></i> System Tools</h5>
<div style="background:#2d3748; padding:12px; border-radius:8px; margin-bottom:15px;">
<p style="margin-bottom:10px;">Outils système Linux nécessaires au fonctionnement.</p>
<div style="display:grid; grid-template-columns:1fr 1fr 1fr; gap:8px; font-size:11px;">
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">pwsh</strong> - PowerShell Core</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">python3</strong> - Python interpreter</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">pip3</strong> - Package manager Python</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">google-chrome</strong> - Browser automation</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">chromium</strong> - Browser backup</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">x11vnc</strong> - VNC server</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">Xvfb</strong> - Virtual framebuffer</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">node</strong> - Node.js runtime</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#f6ad55;">psql</strong> - PostgreSQL client</div>
</div>
</div>
<h5 style="color:#22c55e; margin-bottom:15px;"><i class="fab fa-python"></i> Python Packages</h5>
<div style="background:#2d3748; padding:12px; border-radius:8px; margin-bottom:15px;">
<p style="margin-bottom:10px;">Packages Python pour automation, API et traitement de données.</p>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:8px; font-size:11px;">
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">selenium</strong> - Browser automation (FreeDNS Step 8)</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">playwright</strong> - Browser automation moderne</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">requests</strong> - HTTP client (API calls)</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">beautifulsoup4</strong> - HTML parsing</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">cloudflare</strong> - Cloudflare API (Step 7)</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">dnspython</strong> - DNS queries</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">psycopg2-binary</strong> - PostgreSQL adapter</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">paramiko</strong> - SSH connections (FreeDNS server)</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">msal</strong> - Microsoft Auth Library</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">O365</strong> - Microsoft Graph SDK Python</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">pandas</strong> - Data analysis</div>
<div style="background:#1a202c; padding:6px; border-radius:4px;"><strong style="color:#68d391;">openpyxl</strong> - Excel files</div>
</div>
</div>
<h5 style="color:#00d4ff; margin-bottom:15px;"><i class="fas fa-mouse-pointer"></i> Boutons</h5>
<div style="display:flex; gap:10px; flex-wrap:wrap;">
<div style="background:#22c55e; padding:8px 12px; border-radius:6px; font-size:11px; color:#000;">
<strong>✓ Installé</strong> - Outil détecté et fonctionnel
</div>
<div style="background:#6366f1; padding:8px 12px; border-radius:6px; font-size:11px;">
<strong>Tout Installer</strong> - Installe tous les outils de la section
</div>
<div style="background:#00d4ff; padding:8px 12px; border-radius:6px; font-size:11px; color:#000;">
<strong>Vérifier Tout</strong> - Rafraîchit le statut de tous les outils
</div>
</div>
</div>
<div style="margin-top:20px; text-align:right;">
<button onclick="document.getElementById('systemHelpModal').style.display='none'" class="btn btn-primary">Compris !</button>
</div>
</div>
</div>
<?php include("includes/chatbot-widget.php"); ?>
</body>
</html>