From 0ee3c06c777123734c6e18af6b89768e130035d1 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 1 Jan 2020 15:57:33 +0000 Subject: [PATCH 1/5] Fix tooltip percentage computation. While we're at it, also put the blocked queries under permitted ones and show them in gray instead of blue. Signed-off-by: DL6ER --- scripts/pi-hole/js/index.js | 38 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 026b7394..9871a939 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -160,8 +160,8 @@ function updateQueriesOverTime() { timeLineChart.data.labels.push(d); var blocked = data.ads_over_time[1][hour]; var permitted = data.domains_over_time[1][hour] - blocked; - timeLineChart.data.datasets[0].data.push(permitted); - timeLineChart.data.datasets[1].data.push(blocked); + timeLineChart.data.datasets[0].data.push(blocked); + timeLineChart.data.datasets[1].data.push(permitted); } } @@ -764,6 +764,9 @@ $(document).ready(function() { updateSummaryData(); + var blockedColor = "#999999"; + var permittedColor = "#00a65a"; + var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); timeLineChart = new Chart(ctx, { type: "bar", @@ -771,22 +774,22 @@ $(document).ready(function() { labels: [], datasets: [ { - label: "Permitted DNS Queries", + label: "Blocked DNS Queries", fill: true, - backgroundColor: "rgba(0, 166, 90,.8)", - borderColor: "rgba(0, 166, 90,.8)", - pointBorderColor: "rgba(0, 166, 90,.8)", + backgroundColor: blockedColor, + borderColor: blockedColor, + pointBorderColor: blockedColor, pointRadius: 1, pointHoverRadius: 5, data: [], pointHitRadius: 5 }, { - label: "Blocked DNS Queries", + label: "Permitted DNS Queries", fill: true, - backgroundColor: "rgba(0,192,239,1)", - borderColor: "rgba(0,192,239,1)", - pointBorderColor: "rgba(0,192,239,1)", + backgroundColor: permittedColor, + borderColor: permittedColor, + pointBorderColor: permittedColor, pointRadius: 1, pointHoverRadius: 5, data: [], @@ -798,6 +801,9 @@ $(document).ready(function() { tooltips: { enabled: true, mode: "x-axis", + itemSort: function(a, b) { + return b.datasetIndex - a.datasetIndex; + }, callbacks: { title: function(tooltipItem) { var label = tooltipItem[0].xLabel; @@ -806,15 +812,15 @@ $(document).ready(function() { var m = parseInt(time[2], 10) || 0; var from = padNumber(h) + ":" + padNumber(m - 5) + ":00"; var to = padNumber(h) + ":" + padNumber(m + 4) + ":59"; - return "Upstreams from " + from + " to " + to; + return "Queries from " + from + " to " + to; }, label: function(tooltipItems, data) { - if (tooltipItems.datasetIndex === 1) { + if (tooltipItems.datasetIndex === 0) { var percentage = 0.0; - var total = parseInt(data.datasets[0].data[tooltipItems.index]); - var blocked = parseInt(data.datasets[1].data[tooltipItems.index]); - if (total > 0) { - percentage = (100.0 * blocked) / total; + var permitted = parseInt(data.datasets[1].data[tooltipItems.index]); + var blocked = parseInt(data.datasets[0].data[tooltipItems.index]); + if (permitted + blocked > 0) { + percentage = (100.0 * blocked) / (permitted + blocked); } return ( From ac1e68acdedb7376678fbf8703bb4a03bde59bbc Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 1 Jan 2020 18:20:42 +0000 Subject: [PATCH 2/5] Apply the same changes to the long-term graph page. Signed-off-by: DL6ER --- scripts/pi-hole/js/db_graph.js | 59 ++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/scripts/pi-hole/js/db_graph.js b/scripts/pi-hole/js/db_graph.js index aab3eb77..b57ead4b 100644 --- a/scripts/pi-hole/js/db_graph.js +++ b/scripts/pi-hole/js/db_graph.js @@ -160,23 +160,23 @@ function updateQueriesOverTime() { for (hour in dates) { if (Object.prototype.hasOwnProperty.call(dates, hour)) { var date, - dom = 0, - ads = 0; + total = 0, + blocked = 0; date = new Date(1000 * dates[hour]); var idx = data.domains_over_time[0].indexOf(dates[hour].toString()); if (idx > -1) { - dom = data.domains_over_time[1][idx]; + total = data.domains_over_time[1][idx]; } idx = data.ads_over_time[0].indexOf(dates[hour].toString()); if (idx > -1) { - ads = data.ads_over_time[1][idx]; + blocked = data.ads_over_time[1][idx]; } timeLineChart.data.labels.push(date); - timeLineChart.data.datasets[0].data.push(dom - ads); - timeLineChart.data.datasets[1].data.push(ads); + timeLineChart.data.datasets[0].data.push(blocked); + timeLineChart.data.datasets[1].data.push(total - blocked); } } @@ -190,28 +190,30 @@ function updateQueriesOverTime() { $(document).ready(function() { var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); + var blockedColor = "#999999"; + var permittedColor = "#00a65a"; timeLineChart = new Chart(ctx, { type: "bar", data: { labels: [], datasets: [ { - label: "Permitted DNS Queries", + label: "Blocked DNS Queries", fill: true, - backgroundColor: "rgba(0, 166, 90,.8)", - borderColor: "rgba(0, 166, 90,.8)", - pointBorderColor: "rgba(0, 166, 90,.8)", + backgroundColor: blockedColor, + borderColor: blockedColor, + pointBorderColor: blockedColor, pointRadius: 1, pointHoverRadius: 5, data: [], pointHitRadius: 5 }, { - label: "Blocked DNS Queries", + label: "Permitted DNS Queries", fill: true, - backgroundColor: "rgba(0,192,239,1)", - borderColor: "rgba(0,192,239,1)", - pointBorderColor: "rgba(0,192,239,1)", + backgroundColor: permittedColor, + borderColor: permittedColor, + pointBorderColor: permittedColor, pointRadius: 1, pointHoverRadius: 5, data: [], @@ -222,6 +224,9 @@ $(document).ready(function() { options: { tooltips: { enabled: true, + itemSort: function(a, b) { + return b.datasetIndex - a.datasetIndex; + }, mode: "x-axis", callbacks: { title: function(tooltipItem) { @@ -232,8 +237,8 @@ $(document).ready(function() { "-" + padNumber(time.getMonth() + 1) + "-" + - padNumber(time.getDate()) + - " " + + padNumber(time.getDate()); + var from_time = padNumber(time.getHours()) + ":" + padNumber(time.getMinutes()) + @@ -245,22 +250,28 @@ $(document).ready(function() { "-" + padNumber(time.getMonth() + 1) + "-" + - padNumber(time.getDate()) + - " " + + padNumber(time.getDate()); + var until_time = padNumber(time.getHours()) + ":" + padNumber(time.getMinutes()) + ":" + padNumber(time.getSeconds()); - return "Queries from " + from_date + " to " + until_date; + if (from_date === until_date) { + return "Queries from " + from_time + " to " + until_time; + } else { + return ( + "Queries from " + from_date + " " + from_time + " to " + until_date + " " + until_time + ); + } }, label: function(tooltipItems, data) { - if (tooltipItems.datasetIndex === 1) { + if (tooltipItems.datasetIndex === 0) { var percentage = 0.0; - var total = parseInt(data.datasets[0].data[tooltipItems.index]); - var blocked = parseInt(data.datasets[1].data[tooltipItems.index]); - if (total > 0) { - percentage = (100.0 * blocked) / total; + var permitted = parseInt(data.datasets[1].data[tooltipItems.index]); + var blocked = parseInt(data.datasets[0].data[tooltipItems.index]); + if (permitted + blocked > 0) { + percentage = (100.0 * blocked) / (permitted + blocked); } return ( From f2713a9b3d9a986bdccd82bcb00a93ad93f7cbe0 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 2 Jan 2020 13:24:45 +0000 Subject: [PATCH 3/5] Always show date (but only once if the interval is on the same date), break long lines on small displays, and abbreviate gray color definition. Signed-off-by: DL6ER --- scripts/pi-hole/js/db_graph.js | 26 ++++++++++++++++++++------ scripts/pi-hole/js/index.js | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/scripts/pi-hole/js/db_graph.js b/scripts/pi-hole/js/db_graph.js index b57ead4b..8636244d 100644 --- a/scripts/pi-hole/js/db_graph.js +++ b/scripts/pi-hole/js/db_graph.js @@ -190,7 +190,7 @@ function updateQueriesOverTime() { $(document).ready(function() { var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); - var blockedColor = "#999999"; + var blockedColor = "#999"; var permittedColor = "#00a65a"; timeLineChart = new Chart(ctx, { type: "bar", @@ -258,12 +258,26 @@ $(document).ready(function() { ":" + padNumber(time.getSeconds()); if (from_date === until_date) { - return "Queries from " + from_time + " to " + until_time; - } else { - return ( - "Queries from " + from_date + " " + from_time + " to " + until_date + " " + until_time - ); + // Abbreviated form for intervals on the same day + return "Queries from " + from_time + " to " + until_time + " on " + from_date; } + + // Full tooltip for intervals spanning more than one date. + // We split title in two lines on small screens + if ($(window).width() < 992) { + from_date += "\n"; + } + + return ( + "Queries from " + + from_date + + " " + + from_time + + " to " + + until_date + + " " + + until_time + ).split("\n "); }, label: function(tooltipItems, data) { if (tooltipItems.datasetIndex === 0) { diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 9871a939..4f61e62b 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -764,7 +764,7 @@ $(document).ready(function() { updateSummaryData(); - var blockedColor = "#999999"; + var blockedColor = "#999"; var permittedColor = "#00a65a"; var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); From 4337dabff646d39ddab1ddd4f2f04ed4a8f0b9fa Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 2 Jan 2020 13:28:01 +0000 Subject: [PATCH 4/5] Always break tooltip title into two lines on narrow screens. Signed-off-by: DL6ER --- scripts/pi-hole/js/db_graph.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/pi-hole/js/db_graph.js b/scripts/pi-hole/js/db_graph.js index 8636244d..e39f39b3 100644 --- a/scripts/pi-hole/js/db_graph.js +++ b/scripts/pi-hole/js/db_graph.js @@ -257,12 +257,20 @@ $(document).ready(function() { padNumber(time.getMinutes()) + ":" + padNumber(time.getSeconds()); + if (from_date === until_date) { // Abbreviated form for intervals on the same day - return "Queries from " + from_time + " to " + until_time + " on " + from_date; + // We split title in two lines on small screens + if ($(window).width() < 992) { + until_time += "\n"; + } + + return ("Queries from " + from_time + " to " + until_time + " on " + from_date).split( + "\n " + ); } - // Full tooltip for intervals spanning more than one date. + // Full tooltip for intervals spanning more than one day // We split title in two lines on small screens if ($(window).width() < 992) { from_date += "\n"; From f17b216b6b3975089222bf993dbc9df0e0d678b0 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 25 Apr 2020 07:02:37 +0200 Subject: [PATCH 5/5] As of ICU 55.1 (released 2015-04-01) the IDNA2003 APIs are deprecated, because UTS #46 should be preferred over the obsolete IDNA 2003 variant. Implement this change. Fixes #1223 Signed-off-by: DL6ER --- scripts/pi-hole/php/groups.php | 41 ++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/scripts/pi-hole/php/groups.php b/scripts/pi-hole/php/groups.php index 2167295e..7d2fdc5f 100644 --- a/scripts/pi-hole/php/groups.php +++ b/scripts/pi-hole/php/groups.php @@ -391,11 +391,31 @@ if ($_POST['action'] == 'get_groups') { if (extension_loaded("intl") && ($res['type'] === ListType::whitelist || $res['type'] === ListType::blacklist) ) { - $utf8_domain = idn_to_utf8($res['domain']); + + // Try to convert possible IDNA domain to Unicode, we try the UTS #46 standard first + // as this is the new default, see https://sourceforge.net/p/icu/mailman/message/32980778/ + // We know that this fails for some Google domains violating the standard + // see https://github.com/pi-hole/AdminLTE/issues/1223 + $utf8_domain = false; + if (defined("INTL_IDNA_VARIANT_UTS46")) { + // We have to use the option IDNA_NONTRANSITIONAL_TO_ASCII here + // to ensure sparkasse-gießen.de is not converted into + // sparkass-giessen.de but into xn--sparkasse-gieen-2ib.de + // as mandated by the UTS #46 standard + $utf8_domain = idn_to_utf8($res['domain'], IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46); + } + + // If conversion failed, try with the (deprecated!) IDNA 2003 variant + // We have to check for its existance as support of this variant is + // scheduled for removal with PHP 8.0 + // see https://wiki.php.net/rfc/deprecate-and-remove-intl_idna_variant_2003 + if ($utf8_domain === false && defined("INTL_IDNA_VARIANT_2003")) { + $utf8_domain = idn_to_utf8($res['domain'], IDNA_DEFAULT, INTL_IDNA_VARIANT_2003); + } + // Convert domain name to international form // if applicable and extension is available - if($res['domain'] !== $utf8_domain) - { + if ($utf8_domain !== false && $res['domain'] !== $utf8_domain) { $res['domain'] = $utf8_domain.' ('.$res['domain'].')'; } } @@ -428,7 +448,20 @@ if ($_POST['action'] == 'get_groups') { foreach ($domains as $domain) { // Convert domain name to IDNA ASCII form for international domains - $domain = idn_to_ascii($domain); + if (extension_loaded("intl")) { + // Be prepared that this may fail and see our comments above + // (search for "idn_to_utf8) + $idn_domain = false; + if (defined("INTL_IDNA_VARIANT_UTS46")) { + $idn_domain = idn_to_ascii($domain, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46); + } + if ($idn_domain === false && defined("INTL_IDNA_VARIANT_2003")) { + $idn_domain = idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_2003); + } + if($idn_domain !== false) { + $domain = $idn_domain; + } + } if(strlen($_POST['type']) === 2 && $_POST['type'][1] === 'W') {