summaryrefslogtreecommitdiff
path: root/counter.php
diff options
context:
space:
mode:
Diffstat (limited to 'counter.php')
-rw-r--r--counter.php69
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;