Refactoring and cleanup
@@ -55,7 +55,7 @@ class admin_plugin_botmon extends AdminPlugin {
|
||||
<header id="botmon__today__title">Loading …</header>
|
||||
<div id="botmon__today__content">
|
||||
<details id="botmon__today__overview" open>
|
||||
<summary>Bot overview (page views)</summary>
|
||||
<summary>Overview</summary>
|
||||
<div class="botmon_bots_grid">
|
||||
<dl id="botmon__today__botsvshumans"></dl>
|
||||
<dl id="botmon__botslist"></dl>
|
||||
@@ -63,7 +63,7 @@ class admin_plugin_botmon extends AdminPlugin {
|
||||
</div>
|
||||
</details>
|
||||
<details id="botmon__today__webmetrics">
|
||||
<summary>Web metrics</summary>
|
||||
<summary>Web metrics (humans only)</summary>
|
||||
<div class="botmon_webmetrics_grid">
|
||||
<dl id="botmon__today__wm_overview"></dl>
|
||||
<dl id="botmon__today__wm_clients"></dl>
|
||||
|
||||
@@ -1,56 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
sodipodi:docname="bounce.svg"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:zoom="45.17"
|
||||
inkscape:cx="11.932699"
|
||||
inkscape:cy="11.667036"
|
||||
inkscape:window-width="2880"
|
||||
inkscape:window-height="1526"
|
||||
inkscape:window-x="2869"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg1" />
|
||||
<title
|
||||
id="title1">arrow-down-left</title>
|
||||
<metadata
|
||||
id="metadata1">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title>arrow-down-left</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
id="path5"
|
||||
style="display:inline;stroke-linecap:round;stroke-linejoin:round;fill:#666666"
|
||||
d="m 22.931849,5.9601427 -0.02539,0.011719 -5.8125,0.013672 0.855469,1.5898437 C 15.330756,9.3543246 12.785051,11.75936 11.345911,14.573424 10.624405,13.172349 9.7143282,11.824042 8.5177866,10.690612 6.6950096,8.9639776 4.4705243,7.660822 2.1720834,7.401549 a 1,1 0 0 0 -1.1054687,0.8828126 1,1 0 0 0 0.8808594,1.105469 c 1.6749782,0.188944 3.6084113,1.2487544 5.1953125,2.7519534 1.5869012,1.503199 2.8163316,3.434551 3.2421874,5.138672 a 1.0001,1.0001 0 0 0 1.941406,0 c 0.726056,-2.905413 3.583028,-5.850154 6.578125,-7.9296884 l 0.798828,1.4824224 3.210938,-4.8476566 0.02539,-0.013672 h -0.01563 z" />
|
||||
<path
|
||||
style="stroke-linecap:round;stroke-linejoin:round;fill:#666666"
|
||||
d="m 15.587891,15.453125 a 1,1 0 0 0 -1.152344,0.818359 1,1 0 0 0 0.816406,1.152344 c 1.156437,0.197324 1.961737,0.544039 2.414063,0.867188 0.452326,0.323148 0.505938,0.560754 0.505859,0.61914 a 1.0001,1.0001 0 0 0 0,0.002 c 2e-6,-0.0463 0.02551,0.01787 -0.214844,0.210938 -0.240358,0.19307 -0.696402,0.437231 -1.300781,0.642578 -1.208759,0.410694 -2.997996,0.691337 -4.974609,0.691406 C 9.7050274,20.456962 7.9157902,20.176319 6.7070312,19.765625 6.1026518,19.560278 5.6466082,19.316117 5.40625,19.123047 5.1680967,18.931748 5.1929184,18.870194 5.1933594,18.914062 c 6.635e-4,-0.09587 0.046068,-0.303946 0.4648437,-0.609375 0.4202715,-0.306519 1.192284,-0.642512 2.3496094,-0.839843 A 1,1 0 0 0 8.8242188,16.310547 1,1 0 0 0 7.671875,15.492188 c -1.3720499,0.233943 -2.4228357,0.635294 -3.1933594,1.197265 -0.7705236,0.561972 -1.2840155,1.352686 -1.2871093,2.21875 a 1.0001,1.0001 0 0 0 0,0.0039 c 3.64e-5,0.749017 0.4452013,1.353693 0.9628906,1.769532 0.5176892,0.415838 1.1590879,0.721375 1.9101562,0.976562 1.5021367,0.510374 3.4569818,0.798753 5.6171879,0.798828 2.160205,-7.5e-5 4.115051,-0.288454 5.617187,-0.798828 0.751068,-0.255187 1.392467,-0.560723 1.910156,-0.976562 0.517226,-0.415467 0.96206,-1.019489 0.962891,-1.767579 0.0012,-0.904344 -0.553226,-1.687191 -1.34375,-2.251953 -0.790524,-0.564762 -1.864356,-0.974217 -3.240234,-1.208984 z"
|
||||
id="path6" />
|
||||
</svg>
|
||||
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.932,5.96l-0.008,0.012l0.016,-0l-0.026,0.014l-3.211,4.847l-0.798,-1.482c-2.996,2.079 -5.853,5.024 -6.579,7.929c-0.11,0.445 -0.512,0.76 -0.97,0.76c-0.458,-0 -0.861,-0.315 -0.971,-0.76c-0.426,-1.704 -1.655,-3.635 -3.242,-5.138c-1.587,-1.503 -3.521,-2.563 -5.196,-2.752c-0.544,-0.062 -0.942,-0.561 -0.88,-1.106c0.056,-0.503 0.487,-0.889 0.993,-0.889c0.038,0 0.075,0.002 0.112,0.007c2.299,0.259 4.523,1.562 6.346,3.289c1.196,1.133 2.106,2.481 2.828,3.882c1.439,-2.814 3.985,-5.219 6.603,-6.998l-0.855,-1.589l5.812,-0.014l0.026,-0.012Zm-17.738,12.943c0.006,0.012 0.042,0.083 0.212,0.22c0.241,0.193 0.697,0.437 1.301,0.643c1.209,0.41 2.998,0.691 4.975,0.691c1.976,0 3.765,-0.281 4.974,-0.691c0.605,-0.206 1.061,-0.45 1.301,-0.643c0.173,-0.139 0.208,-0.211 0.214,-0.223c-0.006,-0.073 -0.076,-0.302 -0.505,-0.609c-0.452,-0.323 -1.258,-0.67 -2.414,-0.867c-0.54,-0.093 -0.908,-0.613 -0.816,-1.153c0.091,-0.54 0.611,-0.909 1.152,-0.818c1.376,0.235 2.45,0.644 3.24,1.209c0.791,0.565 1.345,1.348 1.344,2.252c-0.001,0.748 -0.446,1.352 -0.963,1.768c-0.518,0.415 -1.159,0.721 -1.91,0.976c-1.502,0.511 -3.457,0.799 -5.617,0.799c-2.161,-0 -4.115,-0.288 -5.618,-0.799c-0.751,-0.255 -1.392,-0.561 -1.91,-0.976c-0.517,-0.416 -0.963,-1.021 -0.963,-1.77l0,-0.004c0.004,-0.866 0.517,-1.657 1.288,-2.219c0.77,-0.562 1.821,-0.963 3.193,-1.197c0.54,-0.091 1.06,0.278 1.152,0.819c0.093,0.54 -0.276,1.061 -0.816,1.154c-1.158,0.197 -1.93,0.533 -2.35,0.84c-0.403,0.294 -0.46,0.497 -0.464,0.598Z" style="fill:#777;"/></svg>
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>information</title><path d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z" style="fill:#9E9E9E"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>information</title><path d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z" style="fill:#777"/></svg>
|
||||
|
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 321 B |
1
img/more.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>Others</title><path d="M4,2A2,2 0 0,0 2,4V14H4V4H14V2H4M8,6A2,2 0 0,0 6,8V18H8V8H18V6H8M20,12V20H12V12H20M20,10H12A2,2 0 0,0 10,12V20A2,2 0 0,0 12,22H20A2,2 0 0,0 22,20V12A2,2 0 0,0 20,10M19,17H17V19H15V17H13V15H15V13H17V15H19V17Z" style="fill:#777"/></svg>
|
||||
|
After Width: | Height: | Size: 324 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>page</title><path d="M6,2A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6M6,4H13V9H18V20H6V4M8,12V14H16V12H8M8,16V18H13V16H8Z" style="fill:#999"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>page</title><path d="M6,2A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6M6,4H13V9H18V20H6V4M8,12V14H16V12H8M8,16V18H13V16H8Z" style="fill:#777"/></svg>
|
||||
|
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 231 B |
BIN
img/referers.png
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 10 KiB |
@@ -1,7 +1,7 @@
|
||||
base botmon
|
||||
author Sascha Leib
|
||||
email ad@hominem.com
|
||||
date 2025-09-15
|
||||
date 2025-09-16
|
||||
name Bot Monitoring
|
||||
desc A tool for monitoring and analysing bot traffic to your wiki (under development)
|
||||
url https://www.dokuwiki.org/plugin:botmon
|
||||
|
||||
316
script.js
@@ -578,9 +578,55 @@ BotMon.live = {
|
||||
BotMon.live.gui.status.hideBusy('Done.');
|
||||
},
|
||||
|
||||
// get a list of known bots:
|
||||
getTopBots: function(max) {
|
||||
//console.info('BotMon.live.data.analytics.getTopBots('+max+')');
|
||||
|
||||
//console.log(BotMon.live.data.analytics.groups.knownBots);
|
||||
|
||||
let botsList = BotMon.live.data.analytics.groups.knownBots.toSorted( (a, b) => {
|
||||
return b._pageViews.length - a._pageViews.length;
|
||||
});
|
||||
|
||||
const other = {
|
||||
'id': 'other',
|
||||
'name': "Others",
|
||||
'count': 0
|
||||
};
|
||||
|
||||
const rList = [];
|
||||
const max2 = ( botsList.length > max ? max-1 : botsList.length );
|
||||
let total = 0; // adding up the items
|
||||
for (let i=0; i<botsList.length; i++) {
|
||||
const it = botsList[i];
|
||||
if (it && it._bot) {
|
||||
if (i < max2) {
|
||||
rList.push({
|
||||
id: it._bot.id,
|
||||
name: (it._bot.n ? it._bot.n : it._bot.id),
|
||||
count: it._pageViews.length
|
||||
});
|
||||
} else {
|
||||
other.count += it._pageViews.length;
|
||||
};
|
||||
total += it._pageViews.length;
|
||||
}
|
||||
};
|
||||
|
||||
// add the "other" item, if needed:
|
||||
if (botsList.length > max2) {
|
||||
rList.push(other);
|
||||
};
|
||||
|
||||
rList.forEach( it => {
|
||||
it.pct = (it.count * 100 / total);
|
||||
});
|
||||
|
||||
return rList;
|
||||
},
|
||||
|
||||
// Referer List:
|
||||
_refererList: [],
|
||||
_refererListCount: 0,
|
||||
_refererList: [],
|
||||
|
||||
addToRefererList: function(ref) {
|
||||
//console.log('BotMon.live.data.analytics.addToRefererList',ref);
|
||||
@@ -592,18 +638,12 @@ BotMon.live = {
|
||||
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 refInfo = me.getRefererInfo(ref);
|
||||
|
||||
// already exists?
|
||||
let refObj = null;
|
||||
for (let i = 0; i < me._refererList.length; i++) {
|
||||
if (me._refererList[i].id == refId) {
|
||||
if (me._refererList[i].id == refInfo.id) {
|
||||
refObj = me._refererList[i];
|
||||
break;
|
||||
}
|
||||
@@ -611,16 +651,31 @@ BotMon.live = {
|
||||
|
||||
// if not exists, create it:
|
||||
if (!refObj) {
|
||||
refObj = {
|
||||
id: refId,
|
||||
count: 0
|
||||
};
|
||||
refObj = refInfo;
|
||||
refObj.count = 1;
|
||||
me._refererList.push(refObj);
|
||||
} else {
|
||||
refObj.count += 1;
|
||||
}
|
||||
// add to total count:
|
||||
me._refererListCount += 1;
|
||||
},
|
||||
|
||||
getRefererInfo: function(url) {
|
||||
//console.log('BotMon.live.data.analytics.getRefererInfo',url);
|
||||
|
||||
// find the referer ID:
|
||||
let refId = 'null';
|
||||
let refName = 'No Referer';
|
||||
if (url && url.host) {
|
||||
const hArr = url.host.split('.');
|
||||
const tld = hArr[hArr.length-1];
|
||||
refId = ( tld == 'localhost' ? tld : hArr[hArr.length-2] + ( tld.length > 3 ? '.' + tld : '' ) );
|
||||
refName = hArr[hArr.length-2] + '.' + tld;
|
||||
}
|
||||
|
||||
return {
|
||||
'id': refId,
|
||||
'n': refName
|
||||
};
|
||||
},
|
||||
|
||||
getTopReferers: function(max) {
|
||||
@@ -628,24 +683,53 @@ BotMon.live = {
|
||||
|
||||
const me = BotMon.live.data.analytics;
|
||||
|
||||
const rList = []; // return array
|
||||
return me._makeTopList(me._refererList, max);
|
||||
},
|
||||
|
||||
_makeTopList: function(arr, max) {
|
||||
//console.info(('BotMon.live.data.analytics._makeTopList(arr,' + max + ')'));
|
||||
|
||||
const me = BotMon.live.data.analytics;
|
||||
|
||||
// sort the list:
|
||||
me._refererList.sort( (a,b) => {
|
||||
arr.sort( (a,b) => {
|
||||
return b.count - a.count;
|
||||
});
|
||||
|
||||
// get the top:
|
||||
for (let i = 0; i < max; i++) {
|
||||
const it = me._refererList[i];
|
||||
const rIt = {
|
||||
id: it.id,
|
||||
count: it.count,
|
||||
pct: (it.count / me._refererListCount * 100).toFixed(0)
|
||||
};
|
||||
rList.push(rIt);
|
||||
const rList = []; // return array
|
||||
const max2 = ( arr.length >= max ? max-1 : arr.length );
|
||||
const other = {
|
||||
'id': 'other',
|
||||
'name': "Others",
|
||||
'count': 0
|
||||
};
|
||||
let total = 0; // adding up the items
|
||||
for (let i=0; Math.min(max, arr.length) > i; i++) {
|
||||
const it = arr[i];
|
||||
if (it) {
|
||||
if (i < max2) {
|
||||
const rIt = {
|
||||
id: it.id,
|
||||
name: (it.n ? it.n : it.id),
|
||||
count: it.count
|
||||
};
|
||||
rList.push(rIt);
|
||||
} else {
|
||||
other.count += it.count;
|
||||
}
|
||||
total += it.count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// add the "other" item, if needed:
|
||||
if (arr.length > max2) {
|
||||
rList.push(other);
|
||||
};
|
||||
|
||||
rList.forEach( it => {
|
||||
it.pct = (it.count * 100 / total);
|
||||
});
|
||||
|
||||
return rList;
|
||||
},
|
||||
|
||||
@@ -687,11 +771,11 @@ BotMon.live = {
|
||||
}
|
||||
|
||||
if (arr) {
|
||||
let cRec = arr.find( it => it.iso == iso);
|
||||
let cRec = arr.find( it => it.id == iso);
|
||||
if (!cRec) {
|
||||
cRec = {
|
||||
'iso': iso,
|
||||
'name': name,
|
||||
'id': iso,
|
||||
'n': name,
|
||||
'count': 1
|
||||
};
|
||||
arr.push(cRec);
|
||||
@@ -730,25 +814,10 @@ BotMon.live = {
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown user type ${type} in function getCountryList.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (arr) {
|
||||
// sort by visit count:
|
||||
arr.sort( (a,b) => b.count - a.count);
|
||||
|
||||
// reduce to only the top (max) items and create the target format:
|
||||
let rList = [];
|
||||
for (let i=0; Math.min(max, arr.length) > i; i++) {
|
||||
const cRec = arr[i];
|
||||
rList.push({
|
||||
'iso': cRec.iso,
|
||||
'name': cRec.name,
|
||||
'count': cRec.count
|
||||
});
|
||||
}
|
||||
return rList;
|
||||
}
|
||||
return [];
|
||||
return me._makeTopList(arr, max);
|
||||
},
|
||||
|
||||
/* browser and platform of human visitors */
|
||||
@@ -766,8 +835,9 @@ BotMon.live = {
|
||||
let bRec = me._browsers.find( it => it.id == browserRec.id);
|
||||
if (!bRec) {
|
||||
bRec = {
|
||||
'id': browserRec.id,
|
||||
'count': 1
|
||||
id: browserRec.id,
|
||||
n: browserRec.n,
|
||||
count: 1
|
||||
};
|
||||
me._browsers.push(bRec);
|
||||
} else {
|
||||
@@ -781,8 +851,9 @@ BotMon.live = {
|
||||
let pRec = me._platforms.find( it => it.id == platformRec.id);
|
||||
if (!pRec) {
|
||||
pRec = {
|
||||
'id': platformRec.id,
|
||||
'count': 1
|
||||
id: platformRec.id,
|
||||
n: platformRec.n,
|
||||
count: 1
|
||||
};
|
||||
me._platforms.push(pRec);
|
||||
} else {
|
||||
@@ -795,84 +866,15 @@ BotMon.live = {
|
||||
getTopBrowsers: function(max) {
|
||||
|
||||
const me = BotMon.live.data.analytics;
|
||||
|
||||
me._browsers.sort( (a,b) => b.count - a.count);
|
||||
|
||||
// how many browsers to show:
|
||||
const max2 = ( me._browsers.length >= max ? max-1 : max );
|
||||
|
||||
const rArr = []; // return array
|
||||
let total = 0;
|
||||
const others = {
|
||||
'id': 'other',
|
||||
'name': "Others",
|
||||
'count': 0
|
||||
};
|
||||
for (let i=0; i < me._browsers.length; i++) {
|
||||
if (i < max2) {
|
||||
rArr.push({
|
||||
'id': me._browsers[i].id,
|
||||
'name': BotMon.live.data.clients.getName(me._browsers[i].id),
|
||||
'count': me._browsers[i].count
|
||||
});
|
||||
total += me._browsers[i].count;
|
||||
} else {
|
||||
others.count += me._browsers[i].count;
|
||||
total += me._browsers[i].count;
|
||||
}
|
||||
};
|
||||
|
||||
if (me._browsers.length > (max-1)) {
|
||||
rArr.push(others);
|
||||
};
|
||||
|
||||
// update percentages:
|
||||
rArr.forEach( it => {
|
||||
it.pct = Math.round(it.count * 100 / total);
|
||||
});
|
||||
|
||||
return rArr;
|
||||
return me._makeTopList(me._browsers, max);
|
||||
},
|
||||
|
||||
getTopPlatforms: function(max) {
|
||||
|
||||
const me = BotMon.live.data.analytics;
|
||||
|
||||
me._platforms.sort( (a,b) => b.count - a.count);
|
||||
// how many browsers to show:
|
||||
const max2 = ( me._platforms.length >= max ? max-1 : max );
|
||||
|
||||
const rArr = []; // return array
|
||||
let total = 0;
|
||||
const others = {
|
||||
'id': 'other',
|
||||
'name': "Others",
|
||||
'count': 0
|
||||
};
|
||||
for (let i=0; i < me._platforms.length; i++) {
|
||||
if (i < max2) {
|
||||
rArr.push({
|
||||
'id': me._platforms[i].id,
|
||||
'name': BotMon.live.data.platforms.getName(me._platforms[i].id),
|
||||
'count': me._platforms[i].count
|
||||
});
|
||||
total += me._platforms[i].count;
|
||||
} else {
|
||||
others.count += me._platforms[i].count;
|
||||
total += me._platforms[i].count;
|
||||
}
|
||||
};
|
||||
|
||||
if (me._platforms.length > (max-1)) {
|
||||
rArr.push(others);
|
||||
};
|
||||
|
||||
// update percentages:
|
||||
rArr.forEach( it => {
|
||||
it.pct = Math.round(it.count * 100 / total);
|
||||
});
|
||||
|
||||
return rArr;
|
||||
return me._makeTopList(me._platforms, max);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1490,14 +1492,16 @@ BotMon.live = {
|
||||
|
||||
const data = BotMon.live.data.analytics.data;
|
||||
|
||||
const maxItemsPerList = 5; // how many list items to show?
|
||||
|
||||
// shortcut for neater code:
|
||||
const makeElement = BotMon.t._makeElement;
|
||||
|
||||
const botsVsHumans = document.getElementById('botmon__today__botsvshumans');
|
||||
if (botsVsHumans) {
|
||||
botsVsHumans.appendChild(makeElement('dt', {}, "Bots vs. Humans"));
|
||||
botsVsHumans.appendChild(makeElement('dt', {}, "Page views by category:"));
|
||||
|
||||
for (let i = 3; i >= 0; i--) {
|
||||
for (let i = 0; i <= 4; i++) {
|
||||
const dd = makeElement('dd');
|
||||
let title = '';
|
||||
let value = '';
|
||||
@@ -1518,6 +1522,10 @@ BotMon.live = {
|
||||
title = "Known bots:";
|
||||
value = data.bots.known;
|
||||
break;
|
||||
case 4:
|
||||
title = "Total:";
|
||||
value = data.totalPageViews;
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown list type ${i}.`);
|
||||
}
|
||||
@@ -1528,20 +1536,20 @@ BotMon.live = {
|
||||
}
|
||||
|
||||
// update known bots list:
|
||||
const botlist = document.getElementById('botmon__botslist'); /* Known bots */
|
||||
botlist.innerHTML = "<dt>Known bots (top 5)</dt>";
|
||||
const botElement = document.getElementById('botmon__botslist'); /* Known bots */
|
||||
if (botElement) {
|
||||
botElement.innerHTML = `<dt>Known bots (top ${maxItemsPerList})</dt>`;
|
||||
|
||||
let bots = BotMon.live.data.analytics.groups.knownBots.toSorted( (a, b) => {
|
||||
return b._pageViews.length - a._pageViews.length;
|
||||
});
|
||||
|
||||
for (let i=0; i < Math.min(bots.length, 5); i++) {
|
||||
const dd = makeElement('dd');
|
||||
dd.appendChild(makeElement('span', {'class': 'has_icon bot bot_' + bots[i]._bot.id }, bots[i]._bot.n));
|
||||
dd.appendChild(makeElement('span', undefined, bots[i]._pageViews.length));
|
||||
botlist.appendChild(dd);
|
||||
let botList = BotMon.live.data.analytics.getTopBots(maxItemsPerList);
|
||||
botList.forEach( (botInfo) => {
|
||||
const bli = makeElement('dd');
|
||||
bli.appendChild(makeElement('span', {'class': 'has_icon bot bot_' + botInfo.id }, botInfo.name));
|
||||
bli.appendChild(makeElement('span', {'class': 'count' }, botInfo.count));
|
||||
botElement.append(bli)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// update the suspected bot IP ranges list:
|
||||
/*const botIps = document.getElementById('botmon__today__botips');
|
||||
if (botIps) {
|
||||
@@ -1559,11 +1567,11 @@ BotMon.live = {
|
||||
// update the top bot countries list:
|
||||
const botCountries = document.getElementById('botmon__today__countries');
|
||||
if (botCountries) {
|
||||
botCountries.appendChild(makeElement('dt', {}, "Bot Countries (top 5)"));
|
||||
botCountries.appendChild(makeElement('dt', {}, `Bot Countries (top ${maxItemsPerList})`));
|
||||
const countryList = BotMon.live.data.analytics.getCountryList('likely_bot', 5);
|
||||
countryList.forEach( (cInfo) => {
|
||||
const cLi = makeElement('dd');
|
||||
cLi.appendChild(makeElement('span', {'class': 'has_icon country ctry_' + cInfo.iso.toLowerCase() }, cInfo.name));
|
||||
cLi.appendChild(makeElement('span', {'class': 'has_icon country ctry_' + cInfo.id.toLowerCase() }, cInfo.name));
|
||||
cLi.appendChild(makeElement('span', {'class': 'count' }, cInfo.count));
|
||||
botCountries.appendChild(cLi);
|
||||
});
|
||||
@@ -1605,9 +1613,9 @@ BotMon.live = {
|
||||
const wmclients = document.getElementById('botmon__today__wm_clients');
|
||||
if (wmclients) {
|
||||
|
||||
wmclients.appendChild(makeElement('dt', {}, "Top browsers"));
|
||||
wmclients.appendChild(makeElement('dt', {}, "Browsers"));
|
||||
|
||||
const clientList = BotMon.live.data.analytics.getTopBrowsers(5);
|
||||
const clientList = BotMon.live.data.analytics.getTopBrowsers(maxItemsPerList);
|
||||
if (clientList) {
|
||||
clientList.forEach( (cInfo) => {
|
||||
const cDd = makeElement('dd');
|
||||
@@ -1615,7 +1623,7 @@ BotMon.live = {
|
||||
cDd.appendChild(makeElement('span', {
|
||||
'class': 'count',
|
||||
'title': cInfo.count + " page views"
|
||||
}, Math.round(cInfo.pct) + '%'));
|
||||
}, cInfo.pct.toFixed(1) + '%'));
|
||||
wmclients.appendChild(cDd);
|
||||
});
|
||||
}
|
||||
@@ -1625,9 +1633,9 @@ BotMon.live = {
|
||||
const wmplatforms = document.getElementById('botmon__today__wm_platforms');
|
||||
if (wmplatforms) {
|
||||
|
||||
wmplatforms.appendChild(makeElement('dt', {}, "Top platforms"));
|
||||
wmplatforms.appendChild(makeElement('dt', {}, "Platforms"));
|
||||
|
||||
const pfList = BotMon.live.data.analytics.getTopPlatforms(5);
|
||||
const pfList = BotMon.live.data.analytics.getTopPlatforms(maxItemsPerList);
|
||||
if (pfList) {
|
||||
pfList.forEach( (pInfo) => {
|
||||
const pDd = makeElement('dd');
|
||||
@@ -1635,7 +1643,7 @@ BotMon.live = {
|
||||
pDd.appendChild(makeElement('span', {
|
||||
'class': 'count',
|
||||
'title': pInfo.count + " page views"
|
||||
}, Math.round(pInfo.pct) + '%'));
|
||||
}, pInfo.pct.toFixed(1) + '%'));
|
||||
wmplatforms.appendChild(pDd);
|
||||
});
|
||||
}
|
||||
@@ -1645,17 +1653,17 @@ BotMon.live = {
|
||||
const wmreferers = document.getElementById('botmon__today__wm_referers');
|
||||
if (wmreferers) {
|
||||
|
||||
wmreferers.appendChild(makeElement('dt', {}, "Top Referers"));
|
||||
wmreferers.appendChild(makeElement('dt', {}, "Referers"));
|
||||
|
||||
const refList = BotMon.live.data.analytics.getTopReferers(5);
|
||||
const refList = BotMon.live.data.analytics.getTopReferers(maxItemsPerList);
|
||||
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': 'has_icon referer ref_' + rInfo.id }, rInfo.name));
|
||||
rDd.appendChild(makeElement('span', {
|
||||
'class': 'count',
|
||||
'title': rInfo.count + " references"
|
||||
}, Math.round(rInfo.pct) + '%'));
|
||||
}, rInfo.pct.toFixed(1) + '%'));
|
||||
wmreferers.appendChild(rDd);
|
||||
});
|
||||
}
|
||||
@@ -1859,6 +1867,15 @@ BotMon.live = {
|
||||
}, ( data._country || "Unknown") ));
|
||||
}
|
||||
|
||||
// referer icons:
|
||||
if ((data._type == BM_USERTYPE.HUMAN || data._type == BM_USERTYPE.LIKELY_BOT) && data.ref) {
|
||||
const refInfo = BotMon.live.data.analytics.getRefererInfo(new URL(data.ref));
|
||||
span1.appendChild(make('span', {
|
||||
'class': 'icon_only referer ref_' + refInfo.id,
|
||||
'title': "Referer: " + data.ref
|
||||
}, refInfo.n));
|
||||
}
|
||||
|
||||
summary.appendChild(span1);
|
||||
const span2 = make('span'); /* right-hand group */
|
||||
|
||||
@@ -1965,9 +1982,6 @@ BotMon.live = {
|
||||
}, data._country + ' (' + data.geo + ')'));
|
||||
}
|
||||
|
||||
/*dl.appendChild(make('dt', {}, "Visitor Type:"));
|
||||
dl.appendChild(make('dd', undefined, data._type ));*/
|
||||
|
||||
dl.appendChild(make('dt', {}, "Session ID:"));
|
||||
dl.appendChild(make('dd', {'class': 'has_icon session typ_' + data.typ}, data.id));
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
&.bot_claude::before { background-position-y: -160px }
|
||||
&.bot_applemsgs::before { background-position-y: -180px }
|
||||
&.bot_reddit::before { background-position-y: -200px }
|
||||
&.bot_other::before { background-image: url('img/more.svg') }
|
||||
|
||||
/* platform icons */
|
||||
&.platform::before { background-image: url('img/platforms.png') }
|
||||
@@ -68,6 +69,7 @@
|
||||
&.pf_hmos::before { background-position-y: -220px }
|
||||
&.pf_tizen::before { background-position-y: -240px }
|
||||
&.pf_fire::before { background-position-y: -260px }
|
||||
&.pf_other::before { background-image: url('img/more.svg') }
|
||||
|
||||
/* browser icons */
|
||||
&.client::before { background-image: url('img/clients.png') }
|
||||
@@ -89,6 +91,7 @@
|
||||
&.cl_chromeold::before { background-position-y: -320px }
|
||||
&.cl_ecosia::before { background-position-y: -340px }
|
||||
&.cl_webkit::before { background-position-y: -360px }
|
||||
&.cl_other::before { background-image: url('img/more.svg') }
|
||||
|
||||
/* Country flags */
|
||||
/* Note: flag images and CSS adapted from: https://github.com/lafeber/world-flags-sprite/ */
|
||||
@@ -353,6 +356,9 @@
|
||||
&.ref_duckduckgo::before { background-position-y: -120px }
|
||||
&.ref_ecosia::before { background-position-y: -140px }
|
||||
&.ref_yandex::before { background-position-y: -160px }
|
||||
&.ref_chatgpt::before { background-position-y: -180px }
|
||||
&.ref_brave::before { background-position-y: -200px }
|
||||
&.ref_other::before { background-image: url('img/more.svg') }
|
||||
}
|
||||
|
||||
/* grid layout for the overview: */
|
||||
|
||||