Add external reference toggle and badges
Some checks failed
docker-build / build (push) Has been cancelled

This commit is contained in:
knight 2025-11-18 23:07:13 -05:00
parent b267a0ecc6
commit 4c20329f36
4 changed files with 55 additions and 4 deletions

View File

@ -384,6 +384,7 @@ def build_query_payload(
use_fuzzy: bool = True, use_fuzzy: bool = True,
use_phrase: bool = True, use_phrase: bool = True,
use_query_string: bool = False, use_query_string: bool = False,
include_external: bool = True,
) -> Dict: ) -> Dict:
filters: List[Dict] = [] filters: List[Dict] = []
should: List[Dict] = [] should: List[Dict] = []
@ -396,6 +397,9 @@ def build_query_payload(
if year_filter: if year_filter:
filters.append(year_filter) filters.append(year_filter)
if not include_external:
filters.append({"bool": {"must_not": [{"term": {"external_reference": True}}]}})
if use_query_string: if use_query_string:
base_fields = ["title^3", "description^2", "transcript_full", "transcript_secondary_full"] base_fields = ["title^3", "description^2", "transcript_full", "transcript_secondary_full"]
qs_query = (query or "").strip() or "*" qs_query = (query or "").strip() or "*"
@ -916,6 +920,7 @@ def create_app(config: AppConfig = CONFIG) -> Flask:
use_fuzzy = parse_flag("fuzzy", True) use_fuzzy = parse_flag("fuzzy", True)
use_phrase = parse_flag("phrase", True) use_phrase = parse_flag("phrase", True)
use_query_string = parse_flag("query_string", False) use_query_string = parse_flag("query_string", False)
include_external = parse_flag("external", True)
if use_query_string: if use_query_string:
use_exact = use_fuzzy = use_phrase = False use_exact = use_fuzzy = use_phrase = False
@ -928,6 +933,7 @@ def create_app(config: AppConfig = CONFIG) -> Flask:
use_fuzzy=use_fuzzy, use_fuzzy=use_fuzzy,
use_phrase=use_phrase, use_phrase=use_phrase,
use_query_string=use_query_string, use_query_string=use_query_string,
include_external=include_external,
) )
start = page * size start = page * size
if config.elastic.debug: if config.elastic.debug:
@ -1005,6 +1011,7 @@ def create_app(config: AppConfig = CONFIG) -> Flask:
"referenced_by_count": source.get("referenced_by_count", 0), "referenced_by_count": source.get("referenced_by_count", 0),
"referenced_by": source.get("referenced_by", []), "referenced_by": source.get("referenced_by", []),
"video_status": source.get("video_status"), "video_status": source.get("video_status"),
"external_reference": source.get("external_reference"),
} }
) )
@ -1068,6 +1075,7 @@ def create_app(config: AppConfig = CONFIG) -> Flask:
use_exact = parse_flag("exact", True) use_exact = parse_flag("exact", True)
use_fuzzy = parse_flag("fuzzy", True) use_fuzzy = parse_flag("fuzzy", True)
use_phrase = parse_flag("phrase", True) use_phrase = parse_flag("phrase", True)
include_external = parse_flag("external", True)
if use_query_string: if use_query_string:
use_exact = use_fuzzy = use_phrase = False use_exact = use_fuzzy = use_phrase = False
@ -1080,6 +1088,7 @@ def create_app(config: AppConfig = CONFIG) -> Flask:
use_fuzzy=use_fuzzy, use_fuzzy=use_fuzzy,
use_phrase=use_phrase, use_phrase=use_phrase,
use_query_string=use_query_string, use_query_string=use_query_string,
include_external=include_external,
) )
query = search_payload.get("query", {"match_all": {}}) query = search_payload.get("query", {"match_all": {}})

View File

@ -39,6 +39,7 @@
const exactToggle = document.getElementById("exactToggle"); const exactToggle = document.getElementById("exactToggle");
const fuzzyToggle = document.getElementById("fuzzyToggle"); const fuzzyToggle = document.getElementById("fuzzyToggle");
const phraseToggle = document.getElementById("phraseToggle"); const phraseToggle = document.getElementById("phraseToggle");
const externalToggle = document.getElementById("externalToggle");
const queryToggle = document.getElementById("queryStringToggle"); const queryToggle = document.getElementById("queryStringToggle");
const searchBtn = document.getElementById("searchBtn"); const searchBtn = document.getElementById("searchBtn");
const aboutBtn = document.getElementById("aboutBtn"); const aboutBtn = document.getElementById("aboutBtn");
@ -139,6 +140,9 @@
exactToggle.checked = parseBoolParam("exact", true); exactToggle.checked = parseBoolParam("exact", true);
fuzzyToggle.checked = parseBoolParam("fuzzy", true); fuzzyToggle.checked = parseBoolParam("fuzzy", true);
phraseToggle.checked = parseBoolParam("phrase", true); phraseToggle.checked = parseBoolParam("phrase", true);
if (externalToggle) {
externalToggle.checked = parseBoolParam("external", true);
}
queryToggle.checked = parseBoolParam("query_string", false); queryToggle.checked = parseBoolParam("query_string", false);
applyQueryMode(); applyQueryMode();
rememberToggleState(); rememberToggleState();
@ -313,7 +317,7 @@
} }
} }
function updateUrl(q, sort, channels, year, page, size, exact, fuzzy, phrase, queryMode) { function updateUrl(q, sort, channels, year, page, size, exact, fuzzy, phrase, queryMode, includeExternal) {
const next = new URL(window.location.href); const next = new URL(window.location.href);
next.searchParams.set("q", q); next.searchParams.set("q", q);
next.searchParams.set("sort", sort); next.searchParams.set("sort", sort);
@ -331,6 +335,7 @@
next.searchParams.set("fuzzy", fuzzy ? "1" : "0"); next.searchParams.set("fuzzy", fuzzy ? "1" : "0");
next.searchParams.set("phrase", phrase ? "1" : "0"); next.searchParams.set("phrase", phrase ? "1" : "0");
next.searchParams.set("query_string", queryMode ? "1" : "0"); next.searchParams.set("query_string", queryMode ? "1" : "0");
next.searchParams.set("external", includeExternal ? "1" : "0");
history.pushState({}, "", next.toString()); history.pushState({}, "", next.toString());
} }
@ -1193,10 +1198,11 @@ async function updateFrequencyChart(term, channels, year, queryMode, toggles = {
if (queryMode) { if (queryMode) {
params.set("query_string", "1"); params.set("query_string", "1");
} }
const { exact = true, fuzzy = true, phrase = true } = toggles || {}; const { exact = true, fuzzy = true, phrase = true, external = true } = toggles || {};
params.set("exact", exact ? "1" : "0"); params.set("exact", exact ? "1" : "0");
params.set("fuzzy", fuzzy ? "1" : "0"); params.set("fuzzy", fuzzy ? "1" : "0");
params.set("phrase", phrase ? "1" : "0"); params.set("phrase", phrase ? "1" : "0");
params.set("external", external ? "1" : "0");
clearFrequency("Loading timeline…"); clearFrequency("Loading timeline…");
try { try {
@ -1250,6 +1256,13 @@ async function updateFrequencyChart(term, channels, year, queryMode, toggles = {
const headerMain = document.createElement("div"); const headerMain = document.createElement("div");
headerMain.className = "result-header-main"; headerMain.className = "result-header-main";
const badgeDefs = []; const badgeDefs = [];
if (item.external_reference) {
badgeDefs.push({
label: "External",
badgeType: "external",
title: "Indexed from an external reference source",
});
}
if (item.highlightSource && item.highlightSource.primary) { if (item.highlightSource && item.highlightSource.primary) {
badgeDefs.push({ label: "primary transcript", badgeType: "transcript-primary" }); badgeDefs.push({ label: "primary transcript", badgeType: "transcript-primary" });
} }
@ -1516,6 +1529,7 @@ async function updateFrequencyChart(term, channels, year, queryMode, toggles = {
let exact = !!exactToggle.checked; let exact = !!exactToggle.checked;
let fuzzy = !!fuzzyToggle.checked; let fuzzy = !!fuzzyToggle.checked;
let phrase = !!phraseToggle.checked; let phrase = !!phraseToggle.checked;
const includeExternal = externalToggle ? externalToggle.checked : true;
if (queryMode) { if (queryMode) {
exact = false; exact = false;
fuzzy = false; fuzzy = false;
@ -1531,7 +1545,19 @@ async function updateFrequencyChart(term, channels, year, queryMode, toggles = {
currentPage = page; currentPage = page;
if (pushState) { if (pushState) {
updateUrl(q, sort, channels, year, page, size, exact, fuzzy, phrase, queryMode); updateUrl(
q,
sort,
channels,
year,
page,
size,
exact,
fuzzy,
phrase,
queryMode,
includeExternal
);
} }
const params = new URLSearchParams(); const params = new URLSearchParams();
@ -1543,13 +1569,14 @@ async function updateFrequencyChart(term, channels, year, queryMode, toggles = {
params.set("fuzzy", fuzzy ? "1" : "0"); params.set("fuzzy", fuzzy ? "1" : "0");
params.set("phrase", phrase ? "1" : "0"); params.set("phrase", phrase ? "1" : "0");
params.set("query_string", queryMode ? "1" : "0"); params.set("query_string", queryMode ? "1" : "0");
params.set("external", includeExternal ? "1" : "0");
channels.forEach((id) => params.append("channel_id", id)); channels.forEach((id) => params.append("channel_id", id));
if (year) params.set("year", year); if (year) params.set("year", year);
const res = await fetch(`/api/search?${params.toString()}`); const res = await fetch(`/api/search?${params.toString()}`);
const payload = await res.json(); const payload = await res.json();
renderResults(payload, page); renderResults(payload, page);
updateFrequencyChart(q, channels, year, queryMode, { exact, fuzzy, phrase }); updateFrequencyChart(q, channels, year, queryMode, { exact, fuzzy, phrase, external: includeExternal });
} }
searchBtn.addEventListener("click", () => runSearch(0)); searchBtn.addEventListener("click", () => runSearch(0));
@ -1580,6 +1607,9 @@ async function updateFrequencyChart(term, channels, year, queryMode, toggles = {
exactToggle.addEventListener("change", () => { rememberToggleState(); runSearch(0); }); exactToggle.addEventListener("change", () => { rememberToggleState(); runSearch(0); });
fuzzyToggle.addEventListener("change", () => { rememberToggleState(); runSearch(0); }); fuzzyToggle.addEventListener("change", () => { rememberToggleState(); runSearch(0); });
phraseToggle.addEventListener("change", () => { rememberToggleState(); runSearch(0); }); phraseToggle.addEventListener("change", () => { rememberToggleState(); runSearch(0); });
if (externalToggle) {
externalToggle.addEventListener("change", () => runSearch(0));
}
if (queryToggle) { if (queryToggle) {
queryToggle.addEventListener("change", () => { applyQueryMode(); runSearch(0); }); queryToggle.addEventListener("change", () => { applyQueryMode(); runSearch(0); });
} }

View File

@ -81,6 +81,12 @@
<span class="toggle-help">Boost exact phrases inside transcripts.</span> <span class="toggle-help">Boost exact phrases inside transcripts.</span>
</div> </div>
<div class="toggle-item">
<input type="checkbox" id="externalToggle" checked />
<label for="externalToggle">External</label>
<span class="toggle-help">Include externally referenced items.</span>
</div>
<div class="toggle-item"> <div class="toggle-item">
<input type="checkbox" id="queryStringToggle" /> <input type="checkbox" id="queryStringToggle" />
<label for="queryStringToggle">Query string mode</label> <label for="queryStringToggle">Query string mode</label>

View File

@ -571,6 +571,12 @@ body.modal-open {
background: #8f4bff; background: #8f4bff;
} }
.badge--external {
background: #f5d08a;
color: #000;
border: 1px solid #cfa74f;
}
.badge-clickable { .badge-clickable {
cursor: pointer; cursor: pointer;
} }