Reorg
This commit is contained in:
@@ -84,7 +84,7 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin {
|
|||||||
public function insertAdminHeader(Event $event, $param) {
|
public function insertAdminHeader(Event $event, $param) {
|
||||||
|
|
||||||
$event->data['link'][] = ['rel' => 'stylesheet', 'href' => DOKU_BASE.'lib/plugins/botmon/admin.css', 'defer' => 'defer'];
|
$event->data['link'][] = ['rel' => 'stylesheet', 'href' => DOKU_BASE.'lib/plugins/botmon/admin.css', 'defer' => 'defer'];
|
||||||
$event->data['script'][] = ['href' => DOKU_BASE.'lib/plugins/botmon/admin.js', 'defer' => 'defer', '_data' => ''];
|
$event->data['script'][] = ['src' => DOKU_BASE.'lib/plugins/botmon/admin.js', 'defer' => 'defer', '_data' => ''];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
36
admin.css
36
admin.css
@@ -389,7 +389,6 @@
|
|||||||
background-size: 20px;
|
background-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* grid layout for the overview: */
|
/* grid layout for the overview: */
|
||||||
.botmon_bots_grid, .botmon_webmetrics_grid, .botmon_traffic_grid {
|
.botmon_bots_grid, .botmon_webmetrics_grid, .botmon_traffic_grid {
|
||||||
& {
|
& {
|
||||||
@@ -435,7 +434,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* the "today" tab: */
|
/* the "today" tab: */
|
||||||
#botmon__today {
|
#botmon__latest {
|
||||||
|
|
||||||
/* item header */
|
/* item header */
|
||||||
header {
|
header {
|
||||||
@@ -747,13 +746,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the log tab: */
|
||||||
|
#botmon__log {
|
||||||
|
|
||||||
|
#botmon__loglist {
|
||||||
|
& {
|
||||||
|
border: #999 solid 1px;
|
||||||
|
background-color: #F0F0F0;
|
||||||
|
margin: 0; padding: .5em;
|
||||||
|
border-radius: .5em 1pt 1pt .5em;
|
||||||
|
list-style: none inside;
|
||||||
|
display: block;
|
||||||
|
min-height: 24rem;
|
||||||
|
max-height: 32rem;
|
||||||
|
overflow: hidden auto
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
&:nth-child(even) {
|
||||||
|
background-color: #DFDFDF;
|
||||||
|
}
|
||||||
|
&.info { color: #626262; font-style: italic;}
|
||||||
|
&.success { color: #217121; }
|
||||||
|
&.error { color: #bb2929; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dark mode overrides */
|
/* dark mode overrides */
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
body.darkmode.mode_admin #botmon__admin {
|
body.darkmode.mode_admin #botmon__admin {
|
||||||
|
|
||||||
#botmon__today {
|
#botmon__latest {
|
||||||
|
|
||||||
header {
|
header {
|
||||||
background-color: #0c0c0d;
|
background-color: #0c0c0d;
|
||||||
@@ -844,7 +870,7 @@
|
|||||||
}
|
}
|
||||||
/* layout overrides for narrow screens: */
|
/* layout overrides for narrow screens: */
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
#botmon__admin #botmon__today #botmon__today__visitorlists {
|
#botmon__admin #botmon__latest #botmon__today__visitorlists {
|
||||||
dl.visitor_details {
|
dl.visitor_details {
|
||||||
& {
|
& {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -865,7 +891,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 670px) {
|
@media (max-width: 670px) {
|
||||||
#botmon__admin #botmon__today {
|
#botmon__admin #botmon__latest {
|
||||||
.botmon_bots_grid, .botmon_webmetrics_grid, .botmon_traffic_grid {
|
.botmon_bots_grid, .botmon_webmetrics_grid, .botmon_traffic_grid {
|
||||||
& {
|
& {
|
||||||
grid-template-columns: 1fr !important;
|
grid-template-columns: 1fr !important;
|
||||||
|
|||||||
17
admin.js
17
admin.js
@@ -32,8 +32,7 @@ const BotMon = {
|
|||||||
//console.info('BotMon.init()');
|
//console.info('BotMon.init()');
|
||||||
|
|
||||||
// find the plugin basedir:
|
// find the plugin basedir:
|
||||||
this._baseDir = document.currentScript.src.substring(0, document.currentScript.src.indexOf('/exe/'))
|
this._baseDir = document.currentScript.src.substring(0, document.currentScript.src.lastIndexOf('/')+1);
|
||||||
+ '/plugins/botmon/';
|
|
||||||
|
|
||||||
// read the page language from the DOM:
|
// read the page language from the DOM:
|
||||||
this._lang = document.getRootNode().documentElement.lang || this._lang;
|
this._lang = document.getRootNode().documentElement.lang || this._lang;
|
||||||
@@ -186,7 +185,7 @@ const BotMon = {
|
|||||||
/* everything specific to the "Latest" tab is self-contained in the "live" object: */
|
/* everything specific to the "Latest" tab is self-contained in the "live" object: */
|
||||||
BotMon.live = {
|
BotMon.live = {
|
||||||
init: function() {
|
init: function() {
|
||||||
//console.info('BotMon.live.init()');
|
console.info('BotMon.live.init()');
|
||||||
|
|
||||||
// set the title:
|
// set the title:
|
||||||
const tDiff = '<abbr title="Coordinated Universal Time">UTC</abbr> ' + (BotMon._timeDiff != '' ? ` (offset: ${BotMon._timeDiff}` : '' ) + ')';
|
const tDiff = '<abbr title="Coordinated Universal Time">UTC</abbr> ' + (BotMon._timeDiff != '' ? ` (offset: ${BotMon._timeDiff}` : '' ) + ')';
|
||||||
@@ -1011,6 +1010,10 @@ BotMon.live = {
|
|||||||
const me = BotMon.live.data.analytics;
|
const me = BotMon.live.data.analytics;
|
||||||
const ipRanges = BotMon.live.data.ipRanges;
|
const ipRanges = BotMon.live.data.ipRanges;
|
||||||
|
|
||||||
|
// Number of IP address segments to look at:
|
||||||
|
const kIP4Segments = 1;
|
||||||
|
const kIP6Segments = 2;
|
||||||
|
|
||||||
let isp = 'null'; // default ISP id
|
let isp = 'null'; // default ISP id
|
||||||
let name = 'Unknown'; // default ISP name
|
let name = 'Unknown'; // default ISP name
|
||||||
|
|
||||||
@@ -1691,7 +1694,7 @@ BotMon.live = {
|
|||||||
// assign the columns to an object:
|
// assign the columns to an object:
|
||||||
const data = {};
|
const data = {};
|
||||||
cols.forEach( (colVal,i) => {
|
cols.forEach( (colVal,i) => {
|
||||||
colName = columns[i] || `col${i}`;
|
const colName = columns[i] || `col${i}`;
|
||||||
const colValue = (colName == 'ts' ? new Date(colVal) : colVal.trim());
|
const colValue = (colName == 'ts' ? new Date(colVal) : colVal.trim());
|
||||||
data[colName] = colValue;
|
data[colName] = colValue;
|
||||||
});
|
});
|
||||||
@@ -1729,10 +1732,12 @@ BotMon.live = {
|
|||||||
|
|
||||||
gui: {
|
gui: {
|
||||||
init: function() {
|
init: function() {
|
||||||
// init the lists view:
|
console.log('BotMon.live.gui.init()');
|
||||||
this.lists.init();
|
// init sub-objects:
|
||||||
|
BotMon.t._callInit(this);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/* The Overview / web metrics section of the live tab */
|
/* The Overview / web metrics section of the live tab */
|
||||||
overview: {
|
overview: {
|
||||||
/**
|
/**
|
||||||
|
|||||||
32
admin.php
32
admin.php
@@ -35,6 +35,8 @@ class admin_plugin_botmon extends AdminPlugin {
|
|||||||
// display GeoIP data?
|
// display GeoIP data?
|
||||||
$geoIPconf = $this->getConf('geoiplib');
|
$geoIPconf = $this->getConf('geoiplib');
|
||||||
|
|
||||||
|
$hasOldLogFiles = $this->hasOldLogFiles();
|
||||||
|
|
||||||
// spinner animation as SVG image:
|
// spinner animation as SVG image:
|
||||||
$svg = '<svg width="12" height="12" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" id="botmon__today__busy"><defs><linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#666"></stop><stop offset="100%" stop-color="#666"></stop></linearGradient></defs><circle cx="25" cy="25" r="20" fill="none" stroke="url(#gradient)" stroke-width="8" stroke-dasharray="31.4 31.4"><animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s" repeatCount="indefinite"></animateTransform></circle></svg>';
|
$svg = '<svg width="12" height="12" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" id="botmon__today__busy"><defs><linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#666"></stop><stop offset="100%" stop-color="#666"></stop></linearGradient></defs><circle cx="25" cy="25" r="20" fill="none" stroke="url(#gradient)" stroke-width="8" stroke-dasharray="31.4 31.4"><animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s" repeatCount="indefinite"></animateTransform></circle></svg>';
|
||||||
|
|
||||||
@@ -45,15 +47,11 @@ class admin_plugin_botmon extends AdminPlugin {
|
|||||||
<h1>Bot Monitoring Plugin</h1>
|
<h1>Bot Monitoring Plugin</h1>
|
||||||
<nav id="botmon__tabs">
|
<nav id="botmon__tabs">
|
||||||
<ul class="tabs" role="tablist">
|
<ul class="tabs" role="tablist">
|
||||||
<li role="presentation" class="active"><a role="tab" href="#botmon__panel1" aria-controls="botmon__panel1" id="botmon__tab1" aria-selected="true">Latest</a></li>
|
<li role="presentation" class="active"><a role="tab" href="#botmon__latest" aria-controls="botmon__latest" id="botmon__tab1" aria-selected="true">Latest</a></li>
|
||||||
|
<li role="presentation"><a role="tab" href="#botmon__log" aria-controls="botmon__log" id="botmon__tab3">Log</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>';
|
</nav>
|
||||||
|
<article role="tabpanel" id="botmon__latest">
|
||||||
if ($this->hasOldLogFiles()) {
|
|
||||||
echo '<div class="info"><strong>Note:</strong> There are old log files that can be deleted. <a href="' . $pluginPath . '/cleanup.php" target="_blank">Click here</a> to run a delete script, or use <em>cron</em> to automatically delete them.</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '<article role="tabpanel" id="botmon__today"">
|
|
||||||
<h2 class="a11y">Latest data</h2>
|
<h2 class="a11y">Latest data</h2>
|
||||||
<header id="botmon__today__title">Loading …</header>
|
<header id="botmon__today__title">Loading …</header>
|
||||||
<div id="botmon__today__content">
|
<div id="botmon__today__content">
|
||||||
@@ -92,12 +90,26 @@ class admin_plugin_botmon extends AdminPlugin {
|
|||||||
<span id="botmon__today__status">Initialising …</span>
|
<span id="botmon__today__status">Initialising …</span>
|
||||||
</footer>
|
</footer>
|
||||||
</article>
|
</article>
|
||||||
</div><!-- End of BotMon Admin Tool -->';
|
<article role="tabpanel" id="botmon__log">
|
||||||
|
<h2>Process log</h2>
|
||||||
|
<ul id="botmon__loglist">';
|
||||||
|
|
||||||
|
/* proces old logs */
|
||||||
|
if ($hasOldLogFiles) {
|
||||||
|
|
||||||
|
$helper = $this->loadHelper('botmon', true);
|
||||||
|
|
||||||
|
$helper->cleanup();
|
||||||
|
} else {
|
||||||
|
echo '<li>No files to process.</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</article></div><!-- End of BotMon Admin Tool -->';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if there are old log files that can be deleted.
|
* Check if there are old log files to be handled
|
||||||
*
|
*
|
||||||
* @return bool true if there are old log files, false otherwise
|
* @return bool true if there are old log files, false otherwise
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
{"id": "amazon-microsoft", "name": "Amazon or Microsoft"},
|
{"id": "amazon-microsoft", "name": "Amazon or Microsoft"},
|
||||||
{"id": "brasilnet", "name": "BrasilNet"},
|
{"id": "brasilnet", "name": "BrasilNet"},
|
||||||
{"id": "charter", "name": "Charter Communications Inc."},
|
{"id": "charter", "name": "Charter Communications Inc."},
|
||||||
|
{"id": "chinanet", "name": "Chinanet"},
|
||||||
{"id": "cnisp", "name": "China ISP"},
|
{"id": "cnisp", "name": "China ISP"},
|
||||||
{"id": "cnmob", "name": "China Mobile Communications Corp."},
|
{"id": "cnmob", "name": "China Mobile Communications Corp."},
|
||||||
{"id": "google", "name": "Google LLC"},
|
{"id": "google", "name": "Google LLC"},
|
||||||
|
|||||||
50
helper.php
Normal file
50
helper.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BotMon Helper Plugin
|
||||||
|
*
|
||||||
|
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||||
|
* @author Sascha Leib <ad@hominem.info>
|
||||||
|
*/
|
||||||
|
|
||||||
|
use dokuwiki\Extension\Plugin;
|
||||||
|
|
||||||
|
class helper_plugin_botmon extends Plugin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
echo "<li>Processing logfiles …</li>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup function
|
||||||
|
*/
|
||||||
|
public function cleanup() {
|
||||||
|
|
||||||
|
// exclude the following two dates:
|
||||||
|
$today = gmdate('Y-m-d');
|
||||||
|
$yesterday = gmdate('Y-m-d', time() - 86400);
|
||||||
|
|
||||||
|
// scan the log directory and delete all files except for today and yesterday:
|
||||||
|
$dir = scandir(DOKU_PLUGIN . 'botmon/logs');
|
||||||
|
foreach($dir as $file) {
|
||||||
|
$fName = pathinfo($file, PATHINFO_BASENAME);
|
||||||
|
$bName = strtok($fName, '.');
|
||||||
|
|
||||||
|
if ($bName == '' || $bName == 'logfiles' || $bName == 'empty' || $fName == '.htaccess') {
|
||||||
|
// echo "File “{$fName}” ignored.\n";
|
||||||
|
} else if ($bName == $today || $bName == $yesterday) {
|
||||||
|
echo "<li class='info'>File “{$fName}” skipped.</li>\n";
|
||||||
|
} else {
|
||||||
|
if (unlink(DOKU_PLUGIN . 'botmon/logs/' . $file)) {
|
||||||
|
echo "<li class='success'>File “{$fName}” deleted.</li>\n";
|
||||||
|
} else {
|
||||||
|
echo "<li class='error'>File “{$fName}” could not be deleted!</li>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "<li class='info'>Done.</li>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
img/addr.png
BIN
img/addr.png
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.1 KiB |
1
style.less
Normal file
1
style.less
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* This file is no longer in use */
|
||||||
Reference in New Issue
Block a user