diff --git a/README.md b/README.md index 3a659c0..0f699db 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# DokuWiki Monitoring Plugin -Plugin for live-monitoring your DokuWiki instance +# DokuWiki Bot Monitoring Plugin +Plugin for live-monitoring your DokuWiki instance for bot activity #TODO: Work in progress diff --git a/action.php b/action.php index 5c08cbf..2f735ff 100644 --- a/action.php +++ b/action.php @@ -4,13 +4,13 @@ use dokuwiki\Extension\EventHandler; use dokuwiki\Extension\Event; /** - * Action Component for the Monitor Plugin + * Action Component for the Bot Monitoring Plugin * * @license GPL 3 (http://www.gnu.org/licenses/gpl.html) * @author Sascha Leib */ -class action_plugin_monitor extends DokuWiki_Action_Plugin { +class action_plugin_botmon extends DokuWiki_Action_Plugin { /** * Registers a callback functions @@ -37,15 +37,15 @@ class action_plugin_monitor extends DokuWiki_Action_Plugin { ? $INFO['userinfo']['name'] : null); // build the tracker code: - $code = NL . DOKU_TAB . "document._monitor = {'t0': Date.now()};" . NL; + $code = NL . DOKU_TAB . "document._botmon = {'t0': Date.now()};" . NL; if ($username) { - $code .= DOKU_TAB . 'document._monitor.user = "' . $username . '";'. NL; + $code .= DOKU_TAB . 'document._botmon.user = "' . $username . '";'. NL; } $code .= DOKU_TAB . "addEventListener('load',function(){" . NL; $code .= DOKU_TAB . DOKU_TAB . "const e=document.createElement('script');" . NL; $code .= DOKU_TAB . DOKU_TAB . "e.async=true;e.defer=true;" . NL; - $code .= DOKU_TAB . DOKU_TAB . "e.src='".DOKU_BASE."lib/plugins/monitor/client.js';" . NL; + $code .= DOKU_TAB . DOKU_TAB . "e.src='".DOKU_BASE."lib/plugins/botmon/client.js';" . NL; $code .= DOKU_TAB . DOKU_TAB . "document.getElementsByTagName('head')[0].appendChild(e);" . NL; $code .= DOKU_TAB . "});" . NL; diff --git a/admin.php b/admin.php index 68b8121..8124cbc 100644 --- a/admin.php +++ b/admin.php @@ -3,7 +3,7 @@ use dokuwiki\Extension\AdminPlugin; /** - * Trafic Monitoring Plugin + * Bot Monitoring Plugin * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Sascha Leib @@ -13,7 +13,7 @@ use dokuwiki\Extension\AdminPlugin; * All DokuWiki plugins to extend the admin function * need to inherit from this class **/ -class admin_plugin_monitor extends AdminPlugin { +class admin_plugin_botmon extends AdminPlugin { /** * Return the path to the icon being displayed in the main admin menu. @@ -30,30 +30,30 @@ class admin_plugin_monitor extends AdminPlugin { */ public function html() { - $svg = ''; + $svg = ''; /* Plugin Headline */ - echo '
'; - echo '

Monitor Plugin

'; + echo '
'; + echo '

Bot Monitoring Plugin

'; /* tab navigation */ - echo '
'; + echo '
'; } } \ No newline at end of file diff --git a/client.js b/client.js index 818af11..d3dc770 100644 --- a/client.js +++ b/client.js @@ -1,4 +1,4 @@ -monitor_client = { +botmon_client = { init: function() { /* send the page view request: */ @@ -23,9 +23,9 @@ monitor_client = { /* collect the data to send: */ const visit = { 'pg': JSINFO.id, - 'u': document._monitor.user || null, + 'u': document._botmon.user || null, 'lg': navigator.language, - 'lt': ( document._monitor ? Date.now() - document._monitor.t0 : null), + 'lt': ( document._botmon ? Date.now() - document._botmon.t0 : null), 'r': document.referrer /*, 'tz': new Date().getTimezoneOffset(), 'url': window.location.href, @@ -52,7 +52,7 @@ monitor_client = { /* function to call regularly to show the user is still on the page: */ _onHeartbeat: async function(url) { - //console.info('monitor_client._onHeartbeat', url); + //console.info('botmon_client._onHeartbeat', url); try { const response = await fetch(url + '?p=' + encodeURIComponent(JSINFO.id) + '&t=' + Date.now(), { @@ -71,4 +71,4 @@ monitor_client = { } // init the script: -monitor_client.init(); \ No newline at end of file +botmon_client.init(); \ No newline at end of file diff --git a/data/known-platforms.json b/data/known-platforms.json index 198f84e..7231cf3 100644 --- a/data/known-platforms.json +++ b/data/known-platforms.json @@ -19,7 +19,7 @@ "id": "macos", "rx": [ "\\(Macintosh;" ] }, - {"n": "Old Windows Version", + {"n": "Vintage Windows", "id": "winold", "rx": [ "\\(Windows NT (\\d\\.\\d)[;\\s\\)]","Windows (\\d\\.\\d)[;\\s]" ], "bot": 0.4 diff --git a/plugin.info.txt b/plugin.info.txt index 257b5a6..7a8f7e3 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ -base monitor +base botmon author Sascha Leib email ad@hominem.com date 2025-09-01 -name Monitoring -desc Live monitoring traffic on your DokuWiki instance (under development) -url https://www.dokuwiki.org/plugin:monitor +name Bot Monitoring +desc Live monitoring of bot traffic on your DokuWiki instance (under development) +url https://www.dokuwiki.org/plugin:botmon diff --git a/pview.php b/pview.php index 4e66e2b..4e48b28 100644 --- a/pview.php +++ b/pview.php @@ -1,4 +1,4 @@ - */ -const Monitor = { +const BotMon = { init: function() { - //console.info('Monitor.init()'); + console.info('BotMon.init()'); // find the plugin basedir: this._baseDir = document.currentScript.src.substring(0, document.currentScript.src.indexOf('/exe/')) - + '/plugins/monitor/'; + + '/plugins/botmon/'; // read the page language from the DOM: this._lang = document.getRootNode().documentElement.lang || this._lang; // get the time offset: - this._timeDiff = Monitor.t._getTimeOffset(); + this._timeDiff = BotMon.t._getTimeOffset(); // init the sub-objects: - Monitor.t._callInit(this); + BotMon.t._callInit(this); }, _baseDir: null, @@ -31,7 +31,7 @@ const Monitor = { /* helper function to call inits of sub-objects */ _callInit: function(obj) { - //console.info('Monitor.t._callInit(obj=',obj,')'); + //console.info('BotMon.t._callInit(obj=',obj,')'); /* call init / _init on each sub-object: */ Object.keys(obj).forEach( (key,i) => { @@ -67,32 +67,32 @@ const Monitor = { }; /* everything specific to the "Today" tab is self-contained in the "live" object: */ -Monitor.live = { +BotMon.live = { init: function() { - //console.info('Monitor.live.init()'); + //console.info('BotMon.live.init()'); // set the title: - const tDiff = '(UTC' + (Monitor._timeDiff != '' ? `, ${Monitor._timeDiff}` : '' ) + ')'; - Monitor.live.gui.status.setTitle(`Showing data for ${tDiff}`); + const tDiff = '(UTC' + (BotMon._timeDiff != '' ? `, ${BotMon._timeDiff}` : '' ) + ')'; + BotMon.live.gui.status.setTitle(`Data for ${tDiff}`); // init sub-objects: - Monitor.t._callInit(this); + BotMon.t._callInit(this); }, data: { init: function() { - //console.info('Monitor.live.data.init()'); + //console.info('BotMon.live.data.init()'); // call sub-inits: - Monitor.t._callInit(this); + BotMon.t._callInit(this); }, // this will be called when the known json files are done loading: _dispatch: function(file) { - //console.info('Monitor.live.data._dispatch(,',file,')'); + //console.info('BotMon.live.data._dispatch(,',file,')'); // shortcut to make code more readable: - const data = Monitor.live.data; + const data = BotMon.live.data; // set the flags: switch(file) { @@ -112,7 +112,7 @@ Monitor.live = { // are all the flags set? if (data._dispatchBotsLoaded && data._dispatchClientsLoaded && data._dispatchPlatformsLoaded) { // chain the log files loading: - Monitor.live.data.loadLogFile('srv', Monitor.live.data._onServerLogLoaded); + BotMon.live.data.loadLogFile('srv', BotMon.live.data._onServerLogLoaded); } }, // flags to track which data files have been loaded: @@ -122,35 +122,35 @@ Monitor.live = { // event callback, after the server log has been loaded: _onServerLogLoaded: function() { - //console.info('Monitor.live.data._onServerLogLoaded()'); + //console.info('BotMon.live.data._onServerLogLoaded()'); // chain the client log file to load: - Monitor.live.data.loadLogFile('log', Monitor.live.data._onClientLogLoaded); + BotMon.live.data.loadLogFile('log', BotMon.live.data._onClientLogLoaded); }, // event callback, after the client log has been loaded: _onClientLogLoaded: function() { - console.info('Monitor.live.data._onClientLogLoaded()'); + console.info('BotMon.live.data._onClientLogLoaded()'); // chain the ticks file to load: - Monitor.live.data.loadLogFile('tck', Monitor.live.data._onTicksLogLoaded); + BotMon.live.data.loadLogFile('tck', BotMon.live.data._onTicksLogLoaded); }, // event callback, after the tiker log has been loaded: _onTicksLogLoaded: function() { - console.info('Monitor.live.data._onTicksLogLoaded()'); + console.info('BotMon.live.data._onTicksLogLoaded()'); // analyse the data: - Monitor.live.data.analytics.analyseAll(); + BotMon.live.data.analytics.analyseAll(); // sort the data: // #TODO // display the data: - Monitor.live.gui.overview.make(); + BotMon.live.gui.overview.make(); - console.log(Monitor.live.data.model._visitors); + console.log(BotMon.live.data.model._visitors); }, @@ -162,7 +162,7 @@ Monitor.live = { findVisitor: function(id) { // shortcut to make code more readable: - const model = Monitor.live.data.model; + const model = BotMon.live.data.model; // loop over all visitors already registered: for (let i=0; i { @@ -424,36 +424,36 @@ Monitor.live = { bots: { // loads the list of known bots from a JSON file: init: async function() { - //console.info('Monitor.live.data.bots.init()'); + //console.info('BotMon.live.data.bots.init()'); // Load the list of known bots: - Monitor.live.gui.status.showBusy("Loading known bots …"); - const url = Monitor._baseDir + 'data/known-bots.json'; + BotMon.live.gui.status.showBusy("Loading known bots …"); + const url = BotMon._baseDir + 'data/known-bots.json'; try { const response = await fetch(url); if (!response.ok) { throw new Error(`${response.status} ${response.statusText}`); } - Monitor.live.data.bots._list = await response.json(); - Monitor.live.data.bots._ready = true; + BotMon.live.data.bots._list = await response.json(); + BotMon.live.data.bots._ready = true; // TODO: allow using the bots list... } catch (error) { - Monitor.live.gui.status.setError("Error while loading the ’known bots’ file: " + error.message); + BotMon.live.gui.status.setError("Error while loading the ‘known bots’ file: " + error.message); } finally { - Monitor.live.gui.status.hideBusy("Done."); - Monitor.live.data._dispatch('bots') + BotMon.live.gui.status.hideBusy("Status: Done."); + BotMon.live.data._dispatch('bots') } }, // returns bot info if the clientId matches a known bot, null otherwise: match: function(client) { - //console.info('Monitor.live.data.bots.match(',client,')'); + //console.info('BotMon.live.data.bots.match(',client,')'); if (client) { - for (let i=0; i { + BotMon.live.data.clients._list.find(client => { let r = false; for (let j=0; j { + BotMon.live.data.platforms._list.find(platform => { let r = false; for (let j=0; j +
Overview
@@ -694,7 +694,7 @@ Monitor.live = {
Probably humans:${data.bots.human}
Registered users:${data.bots.users}
-
+
Known bots
@@ -705,14 +705,14 @@ Monitor.live = { }, status: { setText: function(txt) { - const el = document.getElementById('monitor__today__status'); - if (el && Monitor.live.gui.status._errorCount <= 0) { + const el = document.getElementById('botmon__today__status'); + if (el && BotMon.live.gui.status._errorCount <= 0) { el.innerText = txt; } }, setTitle: function(html) { - const el = document.getElementById('monitor__today__title'); + const el = document.getElementById('botmon__today__title'); if (el) { el.innerHTML = html; } @@ -720,8 +720,8 @@ Monitor.live = { setError: function(txt) { console.error(txt); - Monitor.live.gui.status._errorCount += 1; - const el = document.getElementById('monitor__today__status'); + BotMon.live.gui.status._errorCount += 1; + const el = document.getElementById('botmon__today__status'); if (el) { el.innerText = "An error occured. See the browser log for details!"; el.classList.add('error'); @@ -730,21 +730,21 @@ Monitor.live = { _errorCount: 0, showBusy: function(txt = null) { - Monitor.live.gui.status._busyCount += 1; - const el = document.getElementById('monitor__today__busy'); + BotMon.live.gui.status._busyCount += 1; + const el = document.getElementById('botmon__today__busy'); if (el) { el.style.display = 'inline-block'; } - if (txt) Monitor.live.gui.status.setText(txt); + if (txt) BotMon.live.gui.status.setText(txt); }, _busyCount: 0, hideBusy: function(txt = null) { - const el = document.getElementById('monitor__today__busy'); - Monitor.live.gui.status._busyCount -= 1; - if (Monitor.live.gui.status._busyCount <= 0) { + const el = document.getElementById('botmon__today__busy'); + BotMon.live.gui.status._busyCount -= 1; + if (BotMon.live.gui.status._busyCount <= 0) { if (el) el.style.display = 'none'; - if (txt) Monitor.live.gui.status.setText(txt); + if (txt) BotMon.live.gui.status.setText(txt); } } } @@ -752,7 +752,7 @@ Monitor.live = { } }; -/* launch only if the Monitor admin panel is open: */ -if (document.getElementById('monitor__admin')) { - Monitor.init(); +/* launch only if the BotMon admin panel is open: */ +if (document.getElementById('botmon__admin')) { + BotMon.init(); } \ No newline at end of file diff --git a/style.less b/style.less index de2c6fd..8ea446f 100644 --- a/style.less +++ b/style.less @@ -1,10 +1,10 @@ -#monitor__admin { +#botmon__admin { section[role="tabpanel"] { margin: .25rem 0; } - #monitor__today { + #botmon__today { header { background-color: #F0F0F0; @@ -40,7 +40,7 @@ } } - #monitor__today__content { + #botmon__today__content { & > details { & { margin: 0 0 1pt 0; diff --git a/tick.php b/tick.php index 2a8ff7b..7efd46c 100644 --- a/tick.php +++ b/tick.php @@ -1,4 +1,4 @@ -