diff --git a/action.php b/action.php
index 0c61dca..c85feaa 100644
--- a/action.php
+++ b/action.php
@@ -54,6 +54,18 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin {
];
/* Write out server-side info to a server log: */
+ $this->writeServerLog($username);
+ }
+
+ /**
+ * Writes data to the server log.
+ *
+ * @return void
+ */
+ private function writeServerLog($username) {
+
+ global $conf;
+ global $INFO;
// what is the session identifier?
$sessionId = $_COOKIE['DokuWiki'] ?? '';
@@ -69,6 +81,7 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin {
// clean the page ID
$pageId = preg_replace('/[\x00-\x1F]/', "\u{FFFD}", $INFO['id'] ?? '');
+ // create the log array:
$logArr = Array(
$_SERVER['REMOTE_ADDR'] ?? '', /* remote IP */
$pageId, /* page ID */
@@ -76,7 +89,9 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin {
$sessionType, /* session ID type */
$username,
$_SERVER['HTTP_USER_AGENT'] ?? '', /* User agent */
- $_SERVER['HTTP_REFERER'] ?? '' /* HTTP Referrer */
+ $_SERVER['HTTP_REFERER'] ?? '', /* HTTP Referrer */
+ substr($conf['lang'],0,2), /* page language */
+ implode(',', array_unique(array_map( function($it) { return substr($it,0,2); }, explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE'])))) /* accepted client languages */
);
//* create the log line */
@@ -96,6 +111,5 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin {
/* Done */
fclose($logfile);
-
}
}
\ No newline at end of file
diff --git a/data/rules.json b/data/rules.json
index 2c049d4..8ddb9cf 100644
--- a/data/rules.json
+++ b/data/rules.json
@@ -29,6 +29,10 @@
"id": "noRefs", "desc": "No referer field",
"bot": 30
},
+ {"func": "matchLang", "params": ["en"],
+ "id": "langMatch", "desc": "Client’s ‘Accept-Language’ header does not match the page language (except English pages)",
+ "bot": 20
+ },
{"func": "clientTest", "params": ["brave"],
"id": "susClient", "desc": "Client identifier that is popular with bot networks",
"bot": 10
@@ -62,6 +66,7 @@
{"from": "124.243.128.0", "to": "124.243.191.255", "isp": "huawei", "loc":"sg"},
{"from": "150.40.128.0", "to": "150.40.255.255", "isp": "huawei", "loc":"hk"},
{"from": "159.138.0.0", "to": "159.138.225.255", "isp": "huawei", "loc":"th"},
+ {"from": "162.128.0.2505", "to": "162.128.127.255", "isp": "zenlayer", "loc":"sg"},
{"from": "166.108.192.0", "to": "166.108.255.255", "isp": "huawei", "loc":"sg"},
{"from": "177.0.0.0", "to": "177.223.255.255", "isp": "ths", "loc":"br"},
{"from": "183.87.32.0", "to": "183.87.159.255", "isp": "huawei", "loc":"hk"},
diff --git a/img/ios.svg b/img/ios.svg
index 81eab92..5c302f1 100644
--- a/img/ios.svg
+++ b/img/ios.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/pview.php b/pview.php
index 4208919..2c5d48a 100644
--- a/pview.php
+++ b/pview.php
@@ -67,7 +67,7 @@ foreach ($logArr as $val) {
/* write the log line to the file */
$logfile = fopen($filename, 'a');
if (!$logfile) {
- http_response_code(500);
+ http_response_code(507);
die("Error: Unable to open log file. Please check file permissions.");
}
diff --git a/script.js b/script.js
index d3350e4..e64d12d 100644
--- a/script.js
+++ b/script.js
@@ -234,7 +234,9 @@ BotMon.live = {
if ( v.id == visitor.id) { /* match the pre-defined IDs */
return v;
} else if (v.ip == visitor.ip && v.agent == visitor.agent) {
- console.warn(`Visitor ID “${v.id}” not found, using matchin IP + User-Agent instead.`);
+ if (v.typ !== 'ip') {
+ console.warn(`Visitor ID “${v.id}” not found, using matchin IP + User-Agent instead.`);
+ }
return v;
}
@@ -285,6 +287,10 @@ BotMon.live = {
visitor._client = BotMon.live.data.clients.match(nv.agent) ?? null; // client info
visitor._platform = BotMon.live.data.platforms.match(nv.agent); // platform info
model._visitors.push(visitor);
+ } else { // update existing
+ if (visitor._firstSeen < nv.ts) {
+ visitor._firstSeen = nv.ts;
+ }
}
// find browser
@@ -307,7 +313,9 @@ BotMon.live = {
(prereg.ref !== undefined && prereg.ref !== '');
// update time stamp for last-seen:
- visitor._lastSeen = nv.ts;
+ if (visitor._lastSeen < nv.ts) {
+ visitor._lastSeen = nv.ts;
+ }
// if needed:
return visitor;
@@ -444,6 +452,8 @@ BotMon.live = {
// shortcut to make code more readable:
const model = BotMon.live.data.model;
+ BotMon.live.gui.status.showBusy("Analysing data …");
+
// loop over all visitors:
model._visitors.forEach( (v) => {
@@ -485,8 +495,8 @@ BotMon.live = {
}
});
- //console.log(this.data);
- //console.log(this.groups);
+ BotMon.live.gui.status.hideBusy('Done.');
+
}
},
@@ -848,7 +858,7 @@ BotMon.live = {
return false;
},
- // unusual combinations of PLatform and Client:
+ // unusual combinations of Platform and Client:
combTest: function(visitor, ...combinations) {
for (let i=0; i