From 259d3b850a516f0f40cddd6bbbb9fd35967e80fd Mon Sep 17 00:00:00 2001 From: Sascha Leib Date: Fri, 5 Sep 2025 12:47:36 +0200 Subject: [PATCH] Data management improvements --- data/known-clients.json | 6 +- data/known-platforms.json | 6 +- data/rules.json | 34 +++++-- img/aol.png | Bin 0 -> 960 bytes img/chromeold.svg | 2 +- img/macos.svg | 1 + script.js | 180 ++++++++++++++++++++------------------ style.less | 6 +- 8 files changed, 136 insertions(+), 99 deletions(-) create mode 100644 img/aol.png create mode 100644 img/macos.svg diff --git a/data/known-clients.json b/data/known-clients.json index dbabeee..bb3e389 100644 --- a/data/known-clients.json +++ b/data/known-clients.json @@ -3,9 +3,13 @@ "id": "opera", "rx": [ "\\sOpera\\/.*?Version\\/(\\S+)", "Opera\\/(\\S+)" ] }, + {"n": "AOL Explorer", + "id": "aol", + "rx": [ "\\sAOL\\s(\\d+\\.\\d+)\\)", "\\sAOLBUILD\\/(\\S+)", "\\sBukaolshop\\s", "\\.aolapp\\/(\\d+\\.\\d+)\\." ] + }, {"n": "Samsung Internet", "id": "samsung", - "rx": [ "\\sSamsungBrowser\\/(\\S+)" ] + "rx": [ "\\sSamsungBrowser[\\/\\s](\\d+\\.\\d+)" ] }, {"n": "UC Browser", "id": "uc", diff --git a/data/known-platforms.json b/data/known-platforms.json index 51c4f60..6b81c72 100644 --- a/data/known-platforms.json +++ b/data/known-platforms.json @@ -19,9 +19,13 @@ "id": "android", "rx": [ "[\\(\\s]Android\\s([^;]+);" ] }, + {"n": "MacOS (old)", + "id": "macosold", + "rx": [ "\\sMac OS X (10_\\d+_\\d+)" ] + }, {"n": "MacOS", "id": "macos", - "rx": [ "\\(Macintosh;" ] + "rx": [ "\\sMac OS X (1[1-9]_\\d+_\\d+)" ] }, {"n": "Vintage Windows", "id": "winold", diff --git a/data/rules.json b/data/rules.json index c4368d8..060b7ee 100644 --- a/data/rules.json +++ b/data/rules.json @@ -1,11 +1,29 @@ { - "ip-ranges": [ - {"range": "191.177.0.0", "mask": 16, "bot": 50} - ], + "threshold": 100, "rules": [ - {"field": "_client", "item": "id", "op": "equals", "value": "chromeold", "bot": 30} - ], - "thresholds": { - "bot": 50 - } + {"func": "obsoleteClient", + "id": "oldClient", "desc": "Visit with obsolete browser version", + "bot": 40 + }, + {"func": "obsoletePlatform", + "id": "oldOS", "desc": "Visit with obsolete platform version", + "bot": 40 + }, + {"func": "noJavaScript", + "id": "noJS", "desc": "Visit with JavaScript disabled", + "bot": 20 + }, + {"func": "smallPageCount", "params": [1], + "id": "onePage", "desc": "Views only a single page", + "bot": 20 + }, + {"func": "noTicks", + "id": "noTicks", "desc": "Visitor did not spend time reading any page", + "bot": 10 + }, + {"func": "noReferences", + "id": "noRefs", "desc": "None of the page views came with a reference field", + "bot": 30 + } + ] } \ No newline at end of file diff --git a/img/aol.png b/img/aol.png new file mode 100644 index 0000000000000000000000000000000000000000..16a15fe7721520ad7e87853fa46d0632bbef99c9 GIT binary patch literal 960 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAF%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl|_8{iY-`v3p`zyJRJ{&Vx{gY##vyxOw=-pvPZ|Ni^_=imN^FIR6rc53yG ztt^`4W? zc^$FoQ1afBub*-h?)t3X|IKN^PnTVP5-$Dee)YHa&_}-$e~KUeS@`|$p8ZPak27uF zZMS7D!;gP&R;)69$F<=#&?B4$9+AZi419+{nDKc2iWH!rM2TxeNpOBzNqJ&XDnmeG zW?qS&pKFMMsh**pg>>et6+kuHQX@RmJUz7-IDi~h1}R2X21X#u3y7tmY*4UjFfxP1 zK>=&X$iyH3q@#d1vz-Mjo&{usz~ada3@?C+U^JSg3_z&~>vp@3Xlx~Oh9v)z$$|*Er2YjE<*zYknApb3+JCbdY!=dUFPZH7@`quJCVD1m4QGj zC)1}%+e3RiLYfj-4lPc&`0IatnEAbX^Ae3x_Rrb8xs%1oW6dY0z);?U@Air|-Cvrg z<8ygaXmqS+y@S)P?s7)Q6OoUnq)eIgr(~bV(VZr5Js9>{T=2Q#`RGJd zU`&zBLxxRrl+JI`+53)H-E#f`hXr#rJx_Z(9yp-%_i>ox`#BAg?-L#@662NH`*8cK zveoOJ_$IJ1ZYsO_f$s`G?_*70!z$)ecBU)({u|!GXWQw!WmpSb+z^4*N00U-bP0l+XkKnO~Y` literal 0 HcmV?d00001 diff --git a/img/chromeold.svg b/img/chromeold.svg index 31a88aa..8160631 100644 --- a/img/chromeold.svg +++ b/img/chromeold.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/img/macos.svg b/img/macos.svg new file mode 100644 index 0000000..89f00e5 --- /dev/null +++ b/img/macos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/script.js b/script.js index 1278677..aa35b5c 100644 --- a/script.js +++ b/script.js @@ -209,6 +209,8 @@ BotMon.live = { } else if (visitor._type == BM_USERTYPE.KNOWN_USER) { /* registered users */ + //if (visitor.id == 'fsmoe7lgqb89t92vt4ju8vdl0q') console.log(visitor); + // visitors match when their names match: if ( v.usr == visitor.usr && v.ip == visitor.ip @@ -219,6 +221,9 @@ BotMon.live = { if ( v.id == visitor.id) { /* match the pre-defined IDs */ return v; + } else if (v.ip == visitor.ip && v.agent == visitor.agent) { + console.info("Visitor ID not found, using matchin IP + User-Agent instead."); + return v; } } @@ -226,18 +231,16 @@ BotMon.live = { return null; // nothing found }, - /* if there is already this visit registered, return it (used for updates) */ - _getVisit: function(visit, view) { + /* if there is already this visit registered, return the page view item */ + _getPageView: function(visit, view) { // shortcut to make code more readable: const model = BotMon.live.data.model; - for (let i=0; i { @@ -494,24 +493,30 @@ BotMon.live = { let botInfo = null; // check for known bots: - if (agent) { - BotList.find(bot => { - let r = false; - for (let j=0; j 1 ? rxr[1] : -1) - }; - r = true; - break; - } - }; - return r; - }); + BotList.find(bot => { + let r = false; + for (let j=0; j 1 ? rxr[1] : -1) + }; + r = true; + break; + } + }; + return r; + }); + + // check for unknown bots: + if (!botInfo) { + const botmatch = agent.match(/[^\s](\w*bot)[\/\s;\),$]/i); + if(botmatch) { + botInfo = {'id': "other", 'n': "Other", "bot": botmatch[0] }; + } } //console.log("botInfo:", botInfo); @@ -928,10 +933,11 @@ BotMon.live = { if (data._type == BM_USERTYPE.KNOWN_BOT) { /* Bot only */ + const botName = ( data._bot && data._bot.n ? data._bot.n : "Unknown"); span1.appendChild(make('span', { /* Bot */ 'class': 'bot bot_' + (data._bot ? data._bot.id : 'unknown'), - 'title': "Bot: " + (data._bot ? data._bot.n : 'Unknown') - }, (data._bot ? data._bot.n : 'Unknown'))); + 'title': "Bot: " + botName + }, botName)); } else if (data._type == BM_USERTYPE.KNOWN_USER) { /* User only */ @@ -1000,14 +1006,14 @@ BotMon.live = { dl.appendChild(make('dt', {}, "Platform:")); /* platform */ dl.appendChild(make('dd', {'class': 'has_icon platform_' + (data._platform ? data._platform.id : 'unknown')}, platformName + ( data._platform.v > 0 ? ' (' + data._platform.v + ')' : '' ) )); + + dl.appendChild(make('dt', {}, "IP-Address:")); + dl.appendChild(make('dd', {'class': 'has_icon ip' + ipType}, data.ip)); + + dl.appendChild(make('dt', {}, "ID:")); + dl.appendChild(make('dd', {'class': 'has_icon ip' + data.typ}, data.id)); } - dl.appendChild(make('dt', {}, "IP-Address:")); - dl.appendChild(make('dd', {'class': 'has_icon ip' + ipType}, data.ip)); - - dl.appendChild(make('dt', {}, "ID:")); - dl.appendChild(make('dd', {'class': 'has_icon ip' + data.typ}, data.id)); - if ((data._lastSeen - data._firstSeen) < 1) { dl.appendChild(make('dt', {}, "Seen:")); dl.appendChild(make('dd', {'class': 'seen'}, data._firstSeen.toLocaleString())); @@ -1041,8 +1047,10 @@ BotMon.live = { } pgLi.appendChild(make('span', {}, page.pg)); - pgLi.appendChild(make('span', {}, page.ref)); - pgLi.appendChild(make('span', {}, visitTimeStr)); + // pgLi.appendChild(make('span', {}, page.ref)); + pgLi.appendChild(make('span', {}, ( page._seenBy ? page._seenBy.join(', ') : '—') + '; ' + page._tickCount)); + pgLi.appendChild(make('span', {}, page._firstSeen.toLocaleString())); + pgLi.appendChild(make('span', {}, page._lastSeen.toLocaleString())); pageList.appendChild(pgLi); }); diff --git a/style.less b/style.less index cbc3b89..f718546 100644 --- a/style.less +++ b/style.less @@ -229,12 +229,13 @@ span.user_known::before { background-image: url('img/user.svg') } /* platform icons */ - span.platform_macos::before, dd.platform_macos::before { background-image: url('img/apple.svg') } span.platform_win10::before, dd.platform_win10::before { background-image: url('img/win11.svg') } + span.platform_macos::before, dd.platform_macos::before { background-image: url('img/apple.svg') } span.platform_linux::before, dd.platform_linux::before { background-image: url('img/linux.svg') } span.platform_ios::before, dd.platform_ios::before { background-image: url('img/ios.svg') } span.platform_android::before, dd.platform_android::before { background-image: url('img/android.svg') } span.platform_winold::before, dd.platform_winold::before { background-image: url('img/winold.png') } + span.platform_macosold::before, dd.platform_macosold::before { background-image: url('img/macos.svg') } span.platform_tizen::before, dd.platform_tizen::before { background-image: url('img/tizen.png') } span.platform_hmos::before, dd.platform_hmos::before { background-image: url('img/hmos.svg') } span.platform_chromium::before, dd.platform_chromium::before { background-image: url('img/chromium.svg') } @@ -253,7 +254,8 @@ span.client_samsung::before, dd.client_samsung::before { background-image: url('img/samsung.svg') } span.client_uc::before, dd.client_uc::before { background-image: url('img/uc.svg') } span.client_huawei::before, dd.client_huawei::before { background-image: url('img/huawei.png') } - span.client_vivaldi::before, dd.client_vivaldi::before { background-image: url('img/vivaldi.png') } + span.client_vivaldi::before, dd.client_vivaldi::before { background-image: url('img/vivaldi.svg') } + span.client_aol::before, dd.client_aol::before { background-image: url('img/aol.png') } /* ip address type */ span.ip6::before, dd.ip6::before { background-image: url('img/ip6.svg') }