/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* global utils:false, apiFailure:false */
var GETDict = {};
$(function () {
GETDict = utils.parseQueryString();
if (GETDict.domain !== undefined) {
$("input[id^='domain']").val(GETDict.domain);
}
if (GETDict.N !== undefined) {
$("#number").val(GETDict.number);
}
});
function doSearch() {
const ta = $("#output");
// process with the current visible domain input field
const q = $("input[id^='domain']:visible").val().trim().toLowerCase();
const N = $("#number").val();
// Partial matching?
const partial = $("#partialMatch").is(":checked");
if (q.length === 0) {
return;
}
var verb = partial ? "partially" : "exactly";
$.ajax({
method: "GET",
url: document.body.dataset.apiurl + "/search/" + encodeURIComponent(q),
async: false,
data: {
partial: partial,
N: N,
},
})
.done(function (data) {
ta.empty();
ta.show();
const res = data.search;
var result = "";
const numDomains = res.domains.length;
result =
"Found " +
numDomains +
" domain" +
(numDomains !== 1 ? "s" : "") +
" " +
verb +
" matching '" +
utils.escapeHtml(q) +
"'" +
(numDomains > 0 ? ":" : ".") +
"
";
for (const domain of res.domains) {
const color = domain.type === "deny" ? "red" : "green";
result +=
" - " +
utils.escapeHtml(domain.domain) +
"
" +
domain.kind +
" " +
domain.type +
" domain
added: " +
utils.renderTimestamp(domain.date_added, "display") +
"
last modified: " +
utils.renderTimestamp(domain.date_modified, "display") +
"
" +
(domain.enabled ? "enabled" : "disabled") +
", used in " +
domain.groups.length +
" group" +
(domain.groups.length === 1 ? "" : "s") +
(domain.comment !== null && domain.comment.length > 0
? '
comment: "' + utils.escapeHtml(domain.comment) + '"'
: "
no comment") +
"
";
}
// Group results in res.gravity by res.gravity[].address
var grouped = {};
for (const list of res.gravity) {
if (grouped[list.address + "_" + list.type] === undefined) {
grouped[list.address + "_" + list.type] = [];
}
grouped[list.address + "_" + list.type].push(list);
}
const numLists = Object.keys(grouped).length;
result +=
"Found " +
numLists +
" list" +
(numLists !== 1 ? "s" : "") +
" " +
verb +
" matching '" +
utils.escapeHtml(q) +
"'" +
(numLists > 0 ? ":" : ".") +
"
";
for (const listId of Object.keys(grouped)) {
const list = grouped[listId][0];
const color = list.type === "block" ? "red" : "green";
result +=
" - " +
utils.escapeHtml(list.address) +
"
" +
list.type +
" list" +
"
added: " +
utils.renderTimestamp(list.date_added, "display") +
"
last modified: " +
utils.renderTimestamp(list.date_modified, "display") +
"
last updated: " +
utils.renderTimestamp(list.date_updated, "display") +
" (" +
list.number.toLocaleString() +
" domains)" +
"
" +
(list.enabled ? "enabled" : "disabled") +
", used in " +
list.groups.length +
" group" +
(list.groups.length === 1 ? "" : "s") +
(list.comment !== null && list.comment.length > 0
? '
comment: "' + utils.escapeHtml(list.comment) + '"'
: "
no comment") +
"
matching entries:
";
for (const lists of grouped[listId]) {
result +=
" - " + utils.escapeHtml(lists.domain) + "
";
}
result += "
";
}
result += "Number of results per type:
";
result +=
" - " +
data.search.results.domains.exact +
" exact domain matches
";
result +=
" - " +
data.search.results.domains.regex +
" regex domain matches
";
result +=
" - " +
data.search.results.gravity.allow +
" allowlist (antigravity) matches
";
result +=
" - " +
data.search.results.gravity.block +
" blocklist (gravity) matches
";
if (
data.search.results.gravity.allow > data.search.parameters.N ||
data.search.results.gravity.block > data.search.parameters.N ||
data.search.results.domains.exact > data.search.parameters.N ||
data.search.results.domains.regex > data.search.parameters.N
) {
result +=
"
Note: " +
"The number of results to return per type is limited to " +
data.search.parameters.N +
" entries.
There are " +
data.search.results.total +
" matching entries in total.
Consider " +
"using a more specific search term or increase N.
";
}
ta.append(result);
})
.fail(function (data) {
apiFailure(data);
});
}
// Handle enter key
$("#domain").on("keypress", function (e) {
if (e.which === 13) {
// Enter was pressed, and the input has focus
doSearch();
}
});
// Handle search buttons
$("button[id='btnSearch']").on("click", function () {
doSearch();
});