diff options
Diffstat (limited to 'counter.php')
| -rw-r--r-- | counter.php | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/counter.php b/counter.php new file mode 100644 index 0000000..0ec74d2 --- /dev/null +++ b/counter.php @@ -0,0 +1,69 @@ +<?php +// sophies.rocks +// Copyright (C) 2026 Zofia Szweda +// This file is part of sophies.rocks. +// sophies.rocks is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// sophies.rocks is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// You should have received a copy of the GNU Affero General Public License +// along with sophies.rocks. If not, see <https://www.gnu.org/licenses/>. +$dbPath = '/var/lib/sophii-counter/counter.db'; +$robotsPath = '/var/www/html/robots.txt'; + +function isKnownBot(string $userAgent, string $robotsPath): bool { + if ($userAgent === '') { + return true; + } + + if (!is_readable($robotsPath)) { + return false; + } + + static $botNames = null; + if ($botNames === null) { + $botNames = []; + foreach (file($robotsPath, FILE_IGNORE_NEW_LINES) as $line) { + if (preg_match('/^User-agent:\s*(.+)$/i', trim($line), $m)) { + $name = trim($m[1]); + if (preg_match('/^[A-Za-z0-9 _\-\.]+$/', $name) && strlen($name) > 2) { + $botNames[] = $name; + } + } + } + } + + foreach ($botNames as $bot) { + if (stripos($userAgent, $bot) !== false) { + return true; + } + } + + $genericPatterns = '/curl|wget|python-requests|go-http-client|scrapy|headless/i'; + if (preg_match($genericPatterns, $userAgent)) { + return true; + } + return false; +} + +$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; +$isBot = isKnownBot($userAgent, $robotsPath); + +$db = new SQLite3($dbPath); +$db->busyTimeout(2000); +$db->exec('CREATE TABLE IF NOT EXISTS hits (id INTEGER PRIMARY KEY, count INTEGER)'); +$db->exec('INSERT OR IGNORE INTO hits (id, count) VALUES (1, 0)'); + +if (!$isBot) { + $stmt = $db->prepare('UPDATE hits SET count = count + 1 WHERE id = 1'); + $stmt->execute(); +} + +$result = $db->querySingle('SELECT count FROM hits WHERE id = 1'); + +header('Content-Type: text/plain'); +echo $result; |
