SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,026
Folders
377
Scanned Size
3.79 GB
PHP Files
791
Editable Text Files
12,310
File viewer
guarded to /htdocs
/newsapi_proxy.php
<?php /* ============================================================ * SIMON ยท NewsAPI Proxy * ------------------------------------------------------------ * Upload to: /htdocs/connlink/test1/ui/newsapi_proxy.php * Reached at: https://www.gaylordsinclair.com/connlink/test1/ui/newsapi_proxy.php * * Purpose: * Keeps the NewsAPI key OFF the browser. SIMON calls this URL; * this file looks up the key from ./secrets.php and calls * newsapi.org server-side, then returns the JSON. * * Quota guard: * Developer plan = 1000 calls / 24h. We cache the response to * disk for CACHE_TTL seconds per unique query, so a running * SIMON dashboard can't burn the quota even if polling fast. * * Query params (passed through to NewsAPI): * endpoint=top-headlines | everything (default: top-headlines) * country=us | gb | ... (top-headlines only) * category=general|business|technology|... (top-headlines only) * q=keywords (everything or headlines) * sources=bbc-news,cnn (comma list, optional) * pageSize=1..100 (default 20) * language=en (default en) * ============================================================ */ header('Content-Type: application/json; charset=utf-8'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, OPTIONS'); if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; } /* ----- load secrets (tries /private/secure/ first, then local) ----- */ function simon_load_secrets() { $candidates = [ // Preferred: outside the web root (IONOS: sibling of htdocs/) dirname($_SERVER['DOCUMENT_ROOT'] ?? '') . '/private/secure/secrets.php', // Fallback: next to this file __DIR__ . '/secrets.php', ]; foreach ($candidates as $path) { if ($path && file_exists($path)) { $s = @include $path; if (is_array($s)) return $s; } } return []; } $secrets = simon_load_secrets(); if (!is_array($secrets) || empty($secrets['NEWSAPI_KEY'])) { http_response_code(500); echo json_encode(['ok'=>false, 'err'=>'NEWSAPI_KEY missing in secrets.php (checked /private/secure/ and local dir)']); exit; } $KEY = $secrets['NEWSAPI_KEY']; /* ----- config ----- */ $CACHE_DIR = __DIR__ . '/cache'; $CACHE_TTL = 300; // 5 minutes per query if (!is_dir($CACHE_DIR)) { @mkdir($CACHE_DIR, 0755, true); } /* ----- sanitize + build upstream URL ----- */ $endpoint = ($_GET['endpoint'] ?? 'top-headlines') === 'everything' ? 'everything' : 'top-headlines'; $allowed = ['country','category','q','sources','pageSize','language','from','to','sortBy','domains']; $params = []; foreach ($allowed as $k) { if (isset($_GET[$k]) && $_GET[$k] !== '') { $params[$k] = $_GET[$k]; } } // sensible defaults if ($endpoint === 'top-headlines' && empty($params['country']) && empty($params['sources']) && empty($params['q'])) { $params['country'] = 'us'; } if (empty($params['pageSize'])) $params['pageSize'] = 20; if (empty($params['language']) && $endpoint === 'everything') $params['language'] = 'en'; /* NewsAPI disallows country/category with sources. Drop them if sources given. */ if (!empty($params['sources'])) { unset($params['country'], $params['category']); } $upstream = 'https://newsapi.org/v2/' . $endpoint . '?' . http_build_query($params); /* ----- cache key / check ----- */ $ckey = sha1($upstream); $cfile = $CACHE_DIR . '/newsapi_' . $ckey . '.json'; if (file_exists($cfile) && (time() - filemtime($cfile)) < $CACHE_TTL) { header('X-SIMON-Cache: HIT'); readfile($cfile); exit; } /* ----- fetch upstream ----- */ $ch = curl_init($upstream); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 12, CURLOPT_HTTPHEADER => [ 'X-Api-Key: ' . $KEY, 'User-Agent: SIMON/1.0 (+https://www.gaylordsinclair.com)', 'Accept: application/json', ], ]); $resp = curl_exec($ch); $http = curl_getinfo($ch, CURLINFO_HTTP_CODE); $err = curl_error($ch); curl_close($ch); if ($resp === false || $http >= 500) { // serve stale cache if we have one if (file_exists($cfile)) { header('X-SIMON-Cache: STALE'); readfile($cfile); exit; } http_response_code(502); echo json_encode(['ok'=>false,'err'=>'upstream failed','detail'=>$err,'status'=>$http]); exit; } // store cache only on success if ($http >= 200 && $http < 300) { @file_put_contents($cfile, $resp, LOCK_EX); } header('X-SIMON-Cache: MISS'); http_response_code($http); echo $resp;
Save file
Quick jump
open a path
Open