Referers Update

This commit is contained in:
Sascha Leib
2025-09-15 22:58:08 +02:00
parent 78395e6c02
commit 7d05fe3bb3
6 changed files with 106 additions and 73 deletions

View File

@@ -121,7 +121,7 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin {
private function getCountryCode() { private function getCountryCode() {
$country = ( $this->ipAddress == 'localhost' ? 'AA' : 'ZZ' ); // default if no geoip is available! $country = ( $this->ipAddress == 'localhost' ? 'local' : 'ZZ' ); // default if no geoip is available!
$lib = $this->getConf('geoiplib'); /* which library to use? (can only be phpgeoip or disabled) */ $lib = $this->getConf('geoiplib'); /* which library to use? (can only be phpgeoip or disabled) */

View File

@@ -56,7 +56,7 @@ class admin_plugin_botmon extends AdminPlugin {
<div id="botmon__today__content"> <div id="botmon__today__content">
<details id="botmon__today__overview" open> <details id="botmon__today__overview" open>
<summary>Bot overview (page views)</summary> <summary>Bot overview (page views)</summary>
<div class="botmon_overview_grid"> <div class="botmon_bots_grid">
<dl id="botmon__today__botsvshumans"></dl> <dl id="botmon__today__botsvshumans"></dl>
<dl id="botmon__botslist"></dl> <dl id="botmon__botslist"></dl>
<dl id="botmon__today__countries"></dl> <dl id="botmon__today__countries"></dl>
@@ -64,10 +64,11 @@ class admin_plugin_botmon extends AdminPlugin {
</details> </details>
<details id="botmon__today__webmetrics"> <details id="botmon__today__webmetrics">
<summary>Web metrics</summary> <summary>Web metrics</summary>
<div class="botmon_overview_grid"> <div class="botmon_webmetrics_grid">
<dl id="botmon__today__wm_overview"></dl> <dl id="botmon__today__wm_overview"></dl>
<dl id="botmon__today__wm_clients"></dl> <dl id="botmon__today__wm_clients"></dl>
<dl id="botmon__today__wm_platforms"></dl> <dl id="botmon__today__wm_platforms"></dl>
<dl id="botmon__today__wm_referers"></dl>
</div> </div>
</details> </details>
<details id="botmon__today__visitors"> <details id="botmon__today__visitors">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
img/referers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

147
script.js
View File

@@ -566,6 +566,11 @@ BotMon.live = {
// add browser and platform statistics: // add browser and platform statistics:
me.addBrowserPlatform(v); me.addBrowserPlatform(v);
// add
v._pageViews.forEach( pv => {
me.addToRefererList(pv._ref);
});
} }
}); });
@@ -573,85 +578,76 @@ BotMon.live = {
BotMon.live.gui.status.hideBusy('Done.'); BotMon.live.gui.status.hideBusy('Done.');
}, },
// visits from IP ranges: // Referer List:
/*_ipRange: { _refererList: [],
ip4: [], _refererListCount: 0,
ip6: []
},*/ addToRefererList: function(ref) {
/** //console.log('BotMon.live.data.analytics.addToRefererList',ref);
* Adds a visit to the IP range statistics.
*
* This helps to identify IP ranges that are used by bots.
*
* @param {string} ip The IP address to add.
*/
/*addToIPRanges: function(ip) {
// #TODO: handle nestled ranges!
const me = BotMon.live.data.analytics; const me = BotMon.live.data.analytics;
const ipv = (ip.indexOf(':') > 0 ? 6 : 4);
// ignore internal references:
if (ref && ref.host == 'denkfehler.online') {
return;
}
// find the referer ID:
let refId = 'null';
if (ref && ref.host) {
const hArr = ref.host.split('.');
const tld = hArr[hArr.length-1];
refId = ( tld == 'localhost' ? tld : hArr[hArr.length-2] + ( tld.length > 3 ? '.' + tld : '' ) );
}
const ipArr = ip.split( ipv == 6 ? ':' : '.'); // already exists?
const maxSegments = (ipv == 6 ? 4 : 3); let refObj = null;
for (let i = 0; i < me._refererList.length; i++) {
let arr = (ipv == 6 ? me._ipRange.ip6 : me._ipRange.ip4); if (me._refererList[i].id == refId) {
refObj = me._refererList[i];
// find any existing segment entry:
it = null;
for (let i=0; i < arr.length; i++) {
const sig = arr[i];
if (sig.seg == ipArr[0]) {
it = sig;
break; break;
} }
} }
// create if not found:
if (!it) {
it = {seg: ipArr[0], count: 1};
//if (i<maxSegments) it.sub = [];
arr.push(it);
} else { // increase count: // if not exists, create it:
if (!refObj) {
it.count += 1; refObj = {
id: refId,
count: 0
};
me._refererList.push(refObj);
} else {
refObj.count += 1;
} }
// add to total count:
},*/ me._refererListCount += 1;
/*getTopBotIPRanges: function(max) { },
getTopReferers: function(max) {
//console.info(('BotMon.live.data.analytics.getTopReferers(' + max + ')'));
const me = BotMon.live.data.analytics; const me = BotMon.live.data.analytics;
const kMinHits = 2; const rList = []; // return array
// combine the ip lists, removing all lower volume branches: // sort the list:
let ipTypes = [4,6]; me._refererList.sort( (a,b) => {
const tmpList = []; return b.count - a.count;
for (let i=0; i<ipTypes.length; i++) { });
const ipType = ipTypes[i];
(ipType == 6 ? me._ipRange.ip6 : me._ipRange.ip4).forEach( it => {
if (it.count > kMinHits) {
it.type = ipType;
tmpList.push(it);
}
});
tmpList.sort( (a,b) => b.count - a.count);
}
// reduce to only the top (max) items and create the target format: // get the top:
// #TODO: handle nestled ranges! for (let i = 0; i < max; i++) {
let rList = []; const it = me._refererList[i];
for (let j=0; Math.min(max, tmpList.length) > j; j++) { const rIt = {
const rangeInfo = tmpList[j]; id: it.id,
rList.push({ count: it.count,
'ip': rangeInfo.seg + ( rangeInfo.type == 4 ? '.x.x.x' : '::x'), pct: (it.count / me._refererListCount * 100).toFixed(0)
'typ': rangeInfo.type, }
'num': rangeInfo.count rList.push(rIt);
});
} }
return rList; return rList;
},*/ },
/* countries of visits */ /* countries of visits */
_countries: { _countries: {
@@ -1609,7 +1605,7 @@ BotMon.live = {
const wmclients = document.getElementById('botmon__today__wm_clients'); const wmclients = document.getElementById('botmon__today__wm_clients');
if (wmclients) { if (wmclients) {
wmclients.appendChild(makeElement('dt', {}, "Top browsers (humans only)")); wmclients.appendChild(makeElement('dt', {}, "Top browsers"));
const clientList = BotMon.live.data.analytics.getTopBrowsers(5); const clientList = BotMon.live.data.analytics.getTopBrowsers(5);
if (clientList) { if (clientList) {
@@ -1629,7 +1625,7 @@ BotMon.live = {
const wmplatforms = document.getElementById('botmon__today__wm_platforms'); const wmplatforms = document.getElementById('botmon__today__wm_platforms');
if (wmplatforms) { if (wmplatforms) {
wmplatforms.appendChild(makeElement('dt', {}, "Top platforms (humans only)")); wmplatforms.appendChild(makeElement('dt', {}, "Top platforms"));
const pfList = BotMon.live.data.analytics.getTopPlatforms(5); const pfList = BotMon.live.data.analytics.getTopPlatforms(5);
if (pfList) { if (pfList) {
@@ -1645,6 +1641,25 @@ BotMon.live = {
} }
} }
// update the top referrers;
const wmreferers = document.getElementById('botmon__today__wm_referers');
if (wmreferers) {
wmreferers.appendChild(makeElement('dt', {}, "Top Referers"));
const refList = BotMon.live.data.analytics.getTopReferers(5);
if (refList) {
refList.forEach( (rInfo) => {
const rDd = makeElement('dd');
rDd.appendChild(makeElement('span', {'class': 'has_icon referer ref_' + rInfo.id }, rInfo.id));
rDd.appendChild(makeElement('span', {
'class': 'count',
'title': rInfo.count + " references"
}, Math.round(rInfo.pct) + '%'));
wmreferers.appendChild(rDd);
});
}
}
} }
}, },
@@ -1978,7 +1993,7 @@ BotMon.live = {
/* add bot evaluation details: */ /* add bot evaluation details: */
if (data._eval) { if (data._eval) {
dl.appendChild(make('dt', {}, "Bot evaluation details:")); dl.appendChild(make('dt', {}, "Bot evaluation:"));
const evalDd = make('dd'); const evalDd = make('dd');
const testList = make('ul',{ const testList = make('ul',{
'class': 'eval' 'class': 'eval'

View File

@@ -40,7 +40,8 @@
/* Bot icons */ /* Bot icons */
&.bot::before { background-image: url('img/bots.png') } &.bot::before { background-image: url('img/bots.png') }
&.bot_googlebot::before, &.bot_googleads::before, &.bot_googleapi::before, &.bot_googleother::before, &.bot_googinspct::before { background-position-y: -20px } &.bot_googlebot::before, &.bot_googleads::before, &.bot_googleapi::before,
&.bot_googleother::before, &.bot_googinspct::before { background-position-y: -20px }
&.bot_bingbot::before { background-position-y: -40px } &.bot_bingbot::before { background-position-y: -40px }
&.bot_applebot::before { background-position-y: -60px } &.bot_applebot::before { background-position-y: -60px }
&.bot_openai::before { background-position-y: -80px } &.bot_openai::before { background-position-y: -80px }
@@ -341,13 +342,23 @@
&.extlink::before { background-image: url('img/links.png') } &.extlink::before { background-image: url('img/links.png') }
&.extlink.dnscheck::before { background-position-y: -20px } &.extlink.dnscheck::before { background-position-y: -20px }
&.extlink.ipinfo::before { background-position-y: -40px } &.extlink.ipinfo::before { background-position-y: -40px }
/* Common referers icons */
&.referer::before { background-image: url('img/referers.png') }
&.ref_null::before { background-position-y: -20px }
&.ref_google::before { background-position-y: -40px }
&.ref_bing::before { background-position-y: -60px }
&.ref_yahoo::before { background-position-y: -80px }
&.ref_dokuwiki::before { background-position-y: -100px }
&.ref_duckduckgo::before { background-position-y: -120px }
&.ref_ecosia::before { background-position-y: -140px }
&.ref_yandex::before { background-position-y: -160px }
} }
/* grid layout for the overview: */ /* grid layout for the overview: */
.botmon_overview_grid { .botmon_bots_grid, .botmon_webmetrics_grid {
& { & {
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 0 .33em; grid-gap: 0 .33em;
} }
dl { dl {
@@ -358,6 +369,12 @@
} }
} }
} }
.botmon_bots_grid {
grid-template-columns: 1fr 1fr 1fr;
}
.botmon_webmetrics_grid {
grid-template-columns: 1fr 1fr 1fr 1fr;
}
/* the "today" tab: */ /* the "today" tab: */
#botmon__today { #botmon__today {
@@ -750,7 +767,7 @@
/* layout overrides for narrow screens: */ /* layout overrides for narrow screens: */
@media (max-width: 670px) { @media (max-width: 670px) {
#botmon__admin { #botmon__admin {
.botmon_overview_grid { .botmon_bots_grid, .botmon_webmetrics_grid {
grid-template-columns: 100%; grid-template-columns: 100%;
} }
} }