domainhunter-panel/api.php
Adrian Miesikowski c6a4bdfe30
Some checks are pending
CI / lint (push) Waiting to run
Deploy / deploy (push) Waiting to run
feat: add auto-refresh and new-domain filter + deploy workflow
2026-02-17 22:59:14 +01:00

118 lines
4.3 KiB
PHP

<?php
header('Content-Type: application/json; charset=utf-8');
$dbPath = __DIR__ . '/data/domainhunter.db';
if (!file_exists($dbPath)) {
http_response_code(500);
echo json_encode(['ok' => false, 'error' => 'DB not found']);
exit;
}
try {
$db = new SQLite3($dbPath, SQLITE3_OPEN_READWRITE);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['ok' => false, 'error' => 'DB open failed']);
exit;
}
$action = $_GET['action'] ?? 'domains';
if ($action === 'domains') {
$q = trim($_GET['q'] ?? '');
$tld = trim($_GET['tld'] ?? '');
$onlyNew = (($_GET['only_new'] ?? '0') === '1');
$runId = $db->querySingle("SELECT value FROM metadata WHERE key='latest_run_id'");
$scannedAt = $db->querySingle("SELECT value FROM metadata WHERE key='latest_scanned_at'");
$stPrev = $db->prepare("SELECT run_id FROM domains WHERE run_id != :run GROUP BY run_id ORDER BY MAX(scanned_at) DESC LIMIT 1");
$stPrev->bindValue(':run', $runId, SQLITE3_TEXT);
$prevRes = $stPrev->execute();
$prev = $prevRes ? $prevRes->fetchArray(SQLITE3_ASSOC) : null;
$prevRunId = $prev['run_id'] ?? '';
$sql = "SELECT d.domain, d.tld, d.score, d.status, d.keywords_json,
CASE
WHEN :prev = '' THEN 1
WHEN EXISTS (SELECT 1 FROM domains p WHERE p.run_id = :prev AND p.domain = d.domain) THEN 0
ELSE 1
END AS is_new
FROM domains d WHERE d.run_id = :run";
if ($q !== '') $sql .= " AND d.domain LIKE :q";
if ($tld !== '') $sql .= " AND d.tld = :tld";
if ($onlyNew) {
$sql .= " AND (CASE WHEN :prev = '' THEN 1 WHEN EXISTS (SELECT 1 FROM domains p WHERE p.run_id = :prev AND p.domain = d.domain) THEN 0 ELSE 1 END) = 1";
}
$sql .= " ORDER BY d.score DESC, d.domain ASC LIMIT 500";
$st = $db->prepare($sql);
$st->bindValue(':run', $runId, SQLITE3_TEXT);
$st->bindValue(':prev', $prevRunId, SQLITE3_TEXT);
if ($q !== '') $st->bindValue(':q', '%' . $q . '%', SQLITE3_TEXT);
if ($tld !== '') $st->bindValue(':tld', $tld, SQLITE3_TEXT);
$res = $st->execute();
$rows = [];
$newCount = 0;
while ($r = $res->fetchArray(SQLITE3_ASSOC)) {
$r['keywords'] = json_decode($r['keywords_json'] ?: '[]', true) ?: [];
$r['is_new'] = intval($r['is_new']) === 1;
if ($r['is_new']) $newCount++;
unset($r['keywords_json']);
$rows[] = $r;
}
echo json_encode([
'ok' => true,
'meta' => [
'runId' => $runId,
'prevRunId' => $prevRunId,
'scannedAt' => $scannedAt,
'count' => count($rows),
'newCount' => $newCount
],
'domains' => $rows,
], JSON_UNESCAPED_UNICODE);
exit;
}
if ($action === 'prices') {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$raw = json_decode(file_get_contents('php://input'), true) ?: [];
$registrar = trim($raw['registrar'] ?? '');
$tld = trim($raw['tld'] ?? '');
$registerPrice = $raw['register_price'] ?? null;
$renewPrice = $raw['renew_price'] ?? null;
if ($registrar === '' || $tld === '') {
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'registrar/tld required']);
exit;
}
$st = $db->prepare("UPDATE registrar_prices SET register_price=:rp, renew_price=:rr, updated_at=datetime('now') WHERE registrar=:r AND tld=:t");
if ($registerPrice === null || $registerPrice === '') $st->bindValue(':rp', null, SQLITE3_NULL);
else $st->bindValue(':rp', floatval($registerPrice), SQLITE3_FLOAT);
if ($renewPrice === null || $renewPrice === '') $st->bindValue(':rr', null, SQLITE3_NULL);
else $st->bindValue(':rr', floatval($renewPrice), SQLITE3_FLOAT);
$st->bindValue(':r', $registrar, SQLITE3_TEXT);
$st->bindValue(':t', $tld, SQLITE3_TEXT);
$st->execute();
echo json_encode(['ok' => true]);
exit;
}
$res = $db->query("SELECT registrar, url, tld, register_price, renew_price, updated_at FROM registrar_prices ORDER BY registrar, tld");
$items = [];
while ($r = $res->fetchArray(SQLITE3_ASSOC)) $items[] = $r;
echo json_encode(['ok' => true, 'items' => $items], JSON_UNESCAPED_UNICODE);
exit;
}
http_response_code(400);
echo json_encode(['ok' => false, 'error' => 'unknown action']);