195 lines
11 KiB
HTML
Executable File
195 lines
11 KiB
HTML
Executable File
<?php include_once("/opt/wevads-arsenal/public/api/wevads-metrics.php");
|
|
|
|
// ISP contacts
|
|
$_isps = $_mdb->query("SELECT isp, COUNT(*) as c FROM send_contacts WHERE status='active' GROUP BY isp ORDER BY COUNT(*) DESC")->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Brain par ISP
|
|
$_brain_isp = $_mdb->query("SELECT isp_target as isp, COUNT(*) as configs, SUM(CASE WHEN is_winner THEN 1 ELSE 0 END) as winners, ROUND(AVG(inbox_rate),1) as avg_inbox, SUM(total_sent) as sent FROM brain_configs WHERE is_active=true GROUP BY isp_target ORDER BY COUNT(*) DESC")->fetchAll(PDO::FETCH_ASSOC);
|
|
$_brain_map = [];
|
|
foreach($_brain_isp as $b) $_brain_map[strtolower($b['isp'])] = $b;
|
|
|
|
// Filters
|
|
$_filters = $_mdb->query("SELECT isp_name, filter_name, filter_type, severity, bypass_method FROM isp_filters ORDER BY isp_name, severity DESC")->fetchAll(PDO::FETCH_ASSOC);
|
|
$_filter_map = [];
|
|
foreach($_filters as $f) $_filter_map[strtolower($f['isp_name'])][] = $f;
|
|
|
|
// Methods
|
|
$_methods = $_mdb->query("SELECT isp_name, country, domains, method, uses_office, uses_gsuite, uses_smtp_direct, max_daily_ip, delay_seconds, notes FROM isp_methods ORDER BY isp_name")->fetchAll(PDO::FETCH_ASSOC);
|
|
$_method_map = [];
|
|
foreach($_methods as $m) $_method_map[strtolower($m['isp_name'])] = $m;
|
|
|
|
// Sends par ISP
|
|
$_sends_isp = $_mdb->query("SELECT recipient_isp as isp, COUNT(*) as sent, SUM(CASE WHEN status='sent' THEN 1 ELSE 0 END) as ok FROM graph_send_log GROUP BY recipient_isp ORDER BY COUNT(*) DESC")->fetchAll(PDO::FETCH_ASSOC);
|
|
$_sends_map = [];
|
|
foreach($_sends_isp as $s) $_sends_map[strtolower($s['isp'])] = $s;
|
|
|
|
$_total_contacts = array_sum(array_column($_isps, 'c'));
|
|
?><!DOCTYPE html><html lang="fr"><head>
|
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
<title>WEVADS — ISP Deliverability Matrix</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
:root{--bg:#060a14;--s:#0c1220;--s2:#111827;--b:#1e293b;--t:#e2e8f0;--d:#64748b;--cy:#22d3ee;--gn:#34d399;--am:#fbbf24;--rd:#f87171;--or:#fb923c;--pu:#a78bfa;--pk:#f472b6;--bl:#60a5fa}
|
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
body{background:var(--bg);color:var(--t);font-family:'DM Sans',system-ui;padding:16px;min-height:100vh}
|
|
.hdr{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;padding-bottom:12px;border-bottom:1px solid var(--b)}
|
|
.hdr h1{font-size:18px;font-weight:700}.hdr h1 span{color:var(--cy)}
|
|
.back{color:var(--d);text-decoration:none;font-size:11px;padding:5px 10px;border:1px solid var(--b);border-radius:5px}
|
|
.back:hover{border-color:var(--cy);color:var(--cy)}
|
|
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-bottom:20px}
|
|
.sc{background:var(--s);border:1px solid var(--b);border-radius:8px;padding:12px;text-align:center}
|
|
.sc .n{font-size:20px;font-weight:700;font-family:'JetBrains Mono',monospace}
|
|
.sc .l{font-size:9px;color:var(--d);text-transform:uppercase;margin-top:3px;letter-spacing:.5px}
|
|
.isp-grid{display:grid;gap:12px;margin-bottom:20px}
|
|
.isp-card{background:var(--s);border:1px solid var(--b);border-radius:10px;overflow:hidden}
|
|
.isp-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--b);cursor:pointer}
|
|
.isp-header:hover{background:var(--s2)}
|
|
.isp-name{font-weight:700;font-size:14px;display:flex;align-items:center;gap:8px}
|
|
.isp-stats{display:flex;gap:16px;font-size:11px;font-family:'JetBrains Mono',monospace}
|
|
.isp-body{padding:16px;display:none}
|
|
.isp-body.open{display:block}
|
|
.sect{margin-bottom:14px}
|
|
.sect h3{font-size:11px;color:var(--d);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px;display:flex;align-items:center;gap:6px}
|
|
.filter-row{display:flex;justify-content:space-between;align-items:center;padding:6px 10px;background:var(--s2);border-radius:6px;margin-bottom:4px;font-size:11px}
|
|
.filter-name{font-weight:600}
|
|
.filter-type{font-size:9px;padding:2px 6px;border-radius:3px;font-weight:600}
|
|
.ft-AUTH{background:rgba(96,165,250,.15);color:var(--bl)}
|
|
.ft-CONTENT{background:rgba(167,139,250,.15);color:var(--pu)}
|
|
.ft-IP{background:rgba(251,191,36,.15);color:var(--am)}
|
|
.sev{font-family:'JetBrains Mono';font-size:10px;font-weight:700}
|
|
.bypass{font-size:10px;color:var(--gn);max-width:200px}
|
|
.method-badge{display:inline-block;padding:3px 8px;border-radius:4px;font-size:9px;font-weight:700}
|
|
.mb-o365{background:rgba(96,165,250,.15);color:var(--bl)}
|
|
.mb-graph{background:rgba(52,211,153,.15);color:var(--gn)}
|
|
.mb-smtp{background:rgba(251,191,36,.15);color:var(--am)}
|
|
.mb-domain{background:rgba(248,113,113,.15);color:var(--rd)}
|
|
.bar{height:6px;border-radius:3px;background:var(--b);overflow:hidden;flex:1}
|
|
.bar-fill{height:100%;border-radius:3px}
|
|
.no-data{color:var(--rd);font-size:10px;font-style:italic}
|
|
table{width:100%;border-collapse:collapse;font-size:11px}
|
|
th{text-align:left;padding:6px;color:var(--d);font-size:9px;text-transform:uppercase;border-bottom:1px solid var(--b)}
|
|
td{padding:6px;border-bottom:1px solid rgba(255,255,255,.03)}
|
|
</style></head><body>
|
|
<div class="hdr">
|
|
<h1>📬 ISP <span>Deliverability Matrix</span></h1>
|
|
<a class="back" href="menu.html">← Menu</a>
|
|
</div>
|
|
|
|
<div class="stats">
|
|
<div class="sc"><div class="n" style="color:var(--cy)"><?=count($_isps)?></div><div class="l">ISPs actifs</div></div>
|
|
<div class="sc"><div class="n" style="color:var(--gn)"><?=number_format($_total_contacts)?></div><div class="l">Contacts total</div></div>
|
|
<div class="sc"><div class="n" style="color:var(--pu)"><?=count($_filters)?></div><div class="l">Filtres mappés</div></div>
|
|
<div class="sc"><div class="n" style="color:var(--or)"><?=count($_methods)?></div><div class="l">Routes configurées</div></div>
|
|
<div class="sc"><div class="n" style="color:var(--bl)"><?=$_W['brain']?></div><div class="l">Brain configs</div></div>
|
|
<div class="sc"><div class="n" style="color:var(--pk)"><?=$_W['winners']?></div><div class="l">Winners</div></div>
|
|
</div>
|
|
|
|
<div class="isp-grid">
|
|
<?php
|
|
foreach($_isps as $i) {
|
|
$isp = $i['isp'];
|
|
$isp_lc = strtolower($isp);
|
|
$isp_uc = strtoupper($isp);
|
|
$contacts = $i['c'];
|
|
$pct = round($contacts / max(1,$_total_contacts) * 100, 1);
|
|
$brain = $_brain_map[$isp_lc] ?? $_brain_map[$isp_uc] ?? null;
|
|
$filters = $_filter_map[$isp_lc] ?? $_filter_map[$isp_uc] ?? [];
|
|
$method = $_method_map[$isp_lc] ?? $_method_map[strtolower(str_replace(' ','',$isp))] ?? null;
|
|
$sends = $_sends_map[$isp_lc] ?? null;
|
|
|
|
// Find method for case-insensitive partial match
|
|
if(!$method) {
|
|
foreach($_method_map as $k=>$v) {
|
|
if(stripos($k, substr($isp,0,4)) !== false) { $method = $v; break; }
|
|
}
|
|
}
|
|
if(!$filters) {
|
|
foreach($_filter_map as $k=>$v) {
|
|
if(stripos($k, substr($isp,0,4)) !== false) { $filters = $v; break; }
|
|
}
|
|
}
|
|
|
|
$configs = $brain ? $brain['configs'] : 0;
|
|
$winners = $brain ? $brain['winners'] : 0;
|
|
$inbox = $brain ? $brain['avg_inbox'] : 0;
|
|
$sent = $sends ? $sends['sent'] : 0;
|
|
$ok = $sends ? $sends['ok'] : 0;
|
|
|
|
$color = count($filters) > 0 ? 'var(--gn)' : 'var(--rd)';
|
|
$mtype = $method ? $method['method'] : 'UNKNOWN';
|
|
$mcls = strpos($mtype,'OFFICE')!==false ? 'mb-o365' : (strpos($mtype,'GRAPH')!==false ? 'mb-graph' : (strpos($mtype,'SMTP')!==false ? 'mb-smtp' : 'mb-domain'));
|
|
?>
|
|
<div class="isp-card">
|
|
<div class="isp-header" onclick="this.nextElementSibling.classList.toggle('open')">
|
|
<div class="isp-name">
|
|
<span style="font-size:18px"><?php
|
|
$flags = ['gmail'=>'📧','hotmail'=>'📮','tonline'=>'🇩🇪','t-online'=>'🇩🇪','gmx'=>'🇩🇪','webde'=>'🇩🇪','web.de'=>'🇩🇪','videotron'=>'🇨🇦','alice'=>'🇮🇹','spectrum'=>'🇺🇸','ziggo'=>'🇳🇱','kpn'=>'🇳🇱','yahoo'=>'📧','outlook'=>'📮','orange'=>'🇫🇷','free'=>'🇫🇷','laposte'=>'🇫🇷','aol'=>'📧','comcast'=>'🇺🇸','proton'=>'🔒','bluewin'=>'🇨🇭'];
|
|
echo $flags[$isp_lc] ?? '🌐';
|
|
?></span>
|
|
<?=strtoupper($isp)?>
|
|
<span class="method-badge <?=$mcls?>"><?=$mtype?></span>
|
|
</div>
|
|
<div class="isp-stats">
|
|
<span style="color:var(--cy)"><?=number_format($contacts)?> contacts</span>
|
|
<span style="color:var(--d)"><?=$pct?>%</span>
|
|
<span style="color:<?=$color?>"><?=count($filters)?> filtres</span>
|
|
<span style="color:var(--or)"><?=$configs?> configs</span>
|
|
<span style="color:var(--gn)"><?=$sent?> envois</span>
|
|
</div>
|
|
</div>
|
|
<div class="isp-body">
|
|
|
|
<?php if(count($filters) > 0): ?>
|
|
<div class="sect">
|
|
<h3>🛡️ Filtres Anti-Spam (<?=count($filters)?>)</h3>
|
|
<?php foreach($filters as $fl): ?>
|
|
<div class="filter-row">
|
|
<span class="filter-name"><?=$fl['filter_name']?></span>
|
|
<span class="filter-type ft-<?=$fl['filter_type']?>"><?=$fl['filter_type']?></span>
|
|
<span class="sev" style="color:<?=$fl['severity']>=8?'var(--rd)':($fl['severity']>=6?'var(--am)':'var(--gn)')?>">Sévérité: <?=$fl['severity']?>/10</span>
|
|
<span class="bypass">✅ <?=$fl['bypass_method']?></span>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="sect"><h3>🛡️ Filtres Anti-Spam</h3><span class="no-data">⚠️ Aucun filtre mappé — scraping nécessaire</span></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if($method): ?>
|
|
<div class="sect">
|
|
<h3>📡 Routing & Config</h3>
|
|
<table>
|
|
<tr><td style="color:var(--d)">Pays</td><td><?=$method['country']?></td><td style="color:var(--d)">Méthode</td><td><span class="method-badge <?=$mcls?>"><?=$method['method']?></span></td></tr>
|
|
<tr><td style="color:var(--d)">Domaines</td><td colspan="3" style="font-size:10px"><?=str_replace(['{','}'],'',$method['domains'])?></td></tr>
|
|
<tr><td style="color:var(--d)">Max/jour/IP</td><td style="color:var(--cy)"><?=number_format($method['max_daily_ip'])?></td><td style="color:var(--d)">Délai</td><td><?=$method['delay_seconds']?>s</td></tr>
|
|
<tr><td style="color:var(--d)">O365</td><td><?=$method['uses_office']=='t'?'✅':'❌'?></td><td style="color:var(--d)">GSuite</td><td><?=$method['uses_gsuite']=='t'?'✅':'❌'?></td></tr>
|
|
</table>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="sect"><h3>📡 Routing</h3><span class="no-data">⚠️ Pas de routing configuré</span></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="sect">
|
|
<h3>🧠 Brain Performance</h3>
|
|
<div style="display:flex;gap:20px;font-family:JetBrains Mono;font-size:12px">
|
|
<div><span style="color:var(--d)">Configs:</span> <span style="color:var(--cy)"><?=$configs?></span></div>
|
|
<div><span style="color:var(--d)">Winners:</span> <span style="color:var(--gn)"><?=$winners?></span></div>
|
|
<div><span style="color:var(--d)">Inbox:</span> <span style="color:<?=$inbox>=80?'var(--gn)':($inbox>=50?'var(--am)':'var(--rd)')?>"><?=$inbox?>%</span></div>
|
|
<div><span style="color:var(--d)">Envois:</span> <span style="color:var(--or)"><?=number_format($sent)?></span></div>
|
|
<div><span style="color:var(--d)">Pool:</span> <span style="color:var(--bl)"><?=number_format($contacts)?></span></div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<?php } ?>
|
|
</div>
|
|
|
|
<script>
|
|
// Auto-open first ISP
|
|
document.querySelector('.isp-body')?.classList.add('open');
|
|
</script>
|
|
<?php include("/opt/wevads-arsenal/public/universal-drill.html"); ?>
|
|
</body></html>
|