diff --git a/action.php b/action.php
index 0535472..982c9f5 100644
--- a/action.php
+++ b/action.php
@@ -121,7 +121,7 @@ class action_plugin_botmon extends DokuWiki_Action_Plugin {
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) */
diff --git a/admin.php b/admin.php
index ade38a3..edfef34 100644
--- a/admin.php
+++ b/admin.php
@@ -56,7 +56,7 @@ class admin_plugin_botmon extends AdminPlugin {
Bot overview (page views)
-
+
@@ -64,10 +64,11 @@ class admin_plugin_botmon extends AdminPlugin {
Web metrics
-
+
diff --git a/img/flags.png b/img/flags.png
index 12a2346..2c5d318 100644
Binary files a/img/flags.png and b/img/flags.png differ
diff --git a/img/referers.png b/img/referers.png
new file mode 100644
index 0000000..2fed645
Binary files /dev/null and b/img/referers.png differ
diff --git a/script.js b/script.js
index 91aa057..e8946e3 100644
--- a/script.js
+++ b/script.js
@@ -566,6 +566,11 @@ BotMon.live = {
// add browser and platform statistics:
me.addBrowserPlatform(v);
+
+ // add
+ v._pageViews.forEach( pv => {
+ me.addToRefererList(pv._ref);
+ });
}
});
@@ -573,85 +578,76 @@ BotMon.live = {
BotMon.live.gui.status.hideBusy('Done.');
},
- // visits from IP ranges:
- /*_ipRange: {
- ip4: [],
- ip6: []
- },*/
- /**
- * 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) {
+ // Referer List:
+ _refererList: [],
+ _refererListCount: 0,
+
+ addToRefererList: function(ref) {
+ //console.log('BotMon.live.data.analytics.addToRefererList',ref);
- // #TODO: handle nestled ranges!
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 ? ':' : '.');
- const maxSegments = (ipv == 6 ? 4 : 3);
-
- let arr = (ipv == 6 ? me._ipRange.ip6 : me._ipRange.ip4);
-
- // 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;
+ // already exists?
+ let refObj = null;
+ for (let i = 0; i < me._refererList.length; i++) {
+ if (me._refererList[i].id == refId) {
+ refObj = me._refererList[i];
break;
}
}
-
- // create if not found:
- if (!it) {
- it = {seg: ipArr[0], count: 1};
- //if (i {
- if (it.count > kMinHits) {
- it.type = ipType;
- tmpList.push(it);
- }
- });
- tmpList.sort( (a,b) => b.count - a.count);
- }
+ // sort the list:
+ me._refererList.sort( (a,b) => {
+ return b.count - a.count;
+ });
- // reduce to only the top (max) items and create the target format:
- // #TODO: handle nestled ranges!
- let rList = [];
- for (let j=0; Math.min(max, tmpList.length) > j; j++) {
- const rangeInfo = tmpList[j];
- rList.push({
- 'ip': rangeInfo.seg + ( rangeInfo.type == 4 ? '.x.x.x' : '::x'),
- 'typ': rangeInfo.type,
- 'num': rangeInfo.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);
}
return rList;
- },*/
+ },
/* countries of visits */
_countries: {
@@ -1609,7 +1605,7 @@ BotMon.live = {
const wmclients = document.getElementById('botmon__today__wm_clients');
if (wmclients) {
- wmclients.appendChild(makeElement('dt', {}, "Top browsers (humans only)"));
+ wmclients.appendChild(makeElement('dt', {}, "Top browsers"));
const clientList = BotMon.live.data.analytics.getTopBrowsers(5);
if (clientList) {
@@ -1629,7 +1625,7 @@ BotMon.live = {
const wmplatforms = document.getElementById('botmon__today__wm_platforms');
if (wmplatforms) {
- wmplatforms.appendChild(makeElement('dt', {}, "Top platforms (humans only)"));
+ wmplatforms.appendChild(makeElement('dt', {}, "Top platforms"));
const pfList = BotMon.live.data.analytics.getTopPlatforms(5);
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: */
if (data._eval) {
- dl.appendChild(make('dt', {}, "Bot evaluation details:"));
+ dl.appendChild(make('dt', {}, "Bot evaluation:"));
const evalDd = make('dd');
const testList = make('ul',{
'class': 'eval'
diff --git a/style.less b/style.less
index 1aabda2..a112e57 100644
--- a/style.less
+++ b/style.less
@@ -40,7 +40,8 @@
/* Bot icons */
&.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_applebot::before { background-position-y: -60px }
&.bot_openai::before { background-position-y: -80px }
@@ -341,13 +342,23 @@
&.extlink::before { background-image: url('img/links.png') }
&.extlink.dnscheck::before { background-position-y: -20px }
&.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: */
- .botmon_overview_grid {
+ .botmon_bots_grid, .botmon_webmetrics_grid {
& {
display: grid;
- grid-template-columns: 1fr 1fr 1fr;
grid-gap: 0 .33em;
}
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: */
#botmon__today {
@@ -750,7 +767,7 @@
/* layout overrides for narrow screens: */
@media (max-width: 670px) {
#botmon__admin {
- .botmon_overview_grid {
+ .botmon_bots_grid, .botmon_webmetrics_grid {
grid-template-columns: 100%;
}
}