Changeset View
Changeset View
Standalone View
Standalone View
swh/web/assets/src/bundles/browse/origin-search.js
/** | /** | ||||
* Copyright (C) 2018-2019 The Software Heritage developers | * Copyright (C) 2018-2019 The Software Heritage developers | ||||
* See the AUTHORS file at the top-level directory of this distribution | * See the AUTHORS file at the top-level directory of this distribution | ||||
* License: GNU Affero General Public License version 3, or any later version | * License: GNU Affero General Public License version 3, or any later version | ||||
* See top-level LICENSE file for more information | * See top-level LICENSE file for more information | ||||
*/ | */ | ||||
import {heapsPermute} from 'utils/heaps-permute'; | |||||
import {handleFetchError} from 'utils/functions'; | import {handleFetchError} from 'utils/functions'; | ||||
const limit = 100; | const limit = 100; | ||||
let linksPrev = []; | let linksPrev = []; | ||||
let linkNext = null; | let linkNext = null; | ||||
let linkCurrent = null; | let linkCurrent = null; | ||||
let inSearch = false; | let inSearch = false; | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | function populateOriginSearchResultsTable(origins) { | ||||
} | } | ||||
inSearch = false; | inSearch = false; | ||||
setTimeout(() => { | setTimeout(() => { | ||||
window.scrollTo(0, 0); | window.scrollTo(0, 0); | ||||
}); | }); | ||||
} | } | ||||
function escapeStringRegexp(str) { | function searchOriginsFirst(searchQueryText, limit) { | ||||
let matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; | |||||
return str.replace(matchOperatorsRe, '%5C$&'); | |||||
} | |||||
function searchOriginsFirst(patterns, limit) { | |||||
let baseSearchUrl; | let baseSearchUrl; | ||||
let searchMetadata = $('#swh-search-origin-metadata').prop('checked'); | let searchMetadata = $('#swh-search-origin-metadata').prop('checked'); | ||||
if (searchMetadata) { | if (searchMetadata) { | ||||
baseSearchUrl = Urls.api_1_origin_metadata_search() + `?fulltext=${patterns}`; | baseSearchUrl = Urls.api_1_origin_metadata_search() + '?fulltext=' + encodeURIComponent(searchQueryText); | ||||
} else { | } else { | ||||
let patternsArray = patterns.trim().replace(/\s+/g, ' ').split(' '); | baseSearchUrl = Urls.api_1_origin_search(searchQueryText); | ||||
for (let i = 0; i < patternsArray.length; ++i) { | |||||
patternsArray[i] = escapeStringRegexp(patternsArray[i]); | |||||
} | |||||
// url length must be less than 4096 for modern browsers | |||||
// assuming average word length, 6 is max patternArray.length | |||||
if (patternsArray.length < 7) { | |||||
let patternsPermut = []; | |||||
heapsPermute(patternsArray, p => patternsPermut.push(p.join('.*'))); | |||||
let regex = patternsPermut.join('|'); | |||||
baseSearchUrl = Urls.api_1_origin_search(regex) + `?regexp=true`; | |||||
} else { | |||||
baseSearchUrl = Urls.api_1_origin_search(patternsArray.join('.*')) + `?regexp=true`; | |||||
} | |||||
} | } | ||||
let withVisit = $('#swh-search-origins-with-visit').prop('checked'); | let withVisit = $('#swh-search-origins-with-visit').prop('checked'); | ||||
let searchUrl = baseSearchUrl + `&limit=${limit}&with_visit=${withVisit}`; | let searchUrl = baseSearchUrl + `?limit=${limit}&with_visit=${withVisit}`; | ||||
searchOrigins(searchUrl); | searchOrigins(searchUrl); | ||||
} | } | ||||
function searchOrigins(searchUrl) { | function searchOrigins(searchUrl) { | ||||
clearOriginSearchResultsTable(); | clearOriginSearchResultsTable(); | ||||
$('.swh-loading').addClass('show'); | $('.swh-loading').addClass('show'); | ||||
let response = fetch(searchUrl) | let response = fetch(searchUrl) | ||||
.then(handleFetchError) | .then(handleFetchError) | ||||
Show All 24 Lines | .catch(response => { | ||||
$('#swh-origin-search-results').hide(); | $('#swh-origin-search-results').hide(); | ||||
$('#swh-no-result').text(`Error ${response.status}: ${response.statusText}`); | $('#swh-no-result').text(`Error ${response.status}: ${response.statusText}`); | ||||
$('#swh-no-result').show(); | $('#swh-no-result').show(); | ||||
}); | }); | ||||
} | } | ||||
function doSearch() { | function doSearch() { | ||||
$('#swh-no-result').hide(); | $('#swh-no-result').hide(); | ||||
let patterns = $('#origins-url-patterns').val(); | let searchQueryText = $('#origins-url-patterns').val(); | ||||
inSearch = true; | inSearch = true; | ||||
// first try to resolve a swh persistent identifier | // first try to resolve a swh persistent identifier | ||||
let resolvePidUrl = Urls.api_1_resolve_swh_pid(patterns); | let resolvePidUrl = Urls.api_1_resolve_swh_pid(searchQueryText); | ||||
fetch(resolvePidUrl) | fetch(resolvePidUrl) | ||||
.then(handleFetchError) | .then(handleFetchError) | ||||
.then(response => response.json()) | .then(response => response.json()) | ||||
.then(data => { | .then(data => { | ||||
// pid has been successfully resolved, | // pid has been successfully resolved, | ||||
// so redirect to browse page | // so redirect to browse page | ||||
window.location = data.browse_url; | window.location = data.browse_url; | ||||
}) | }) | ||||
.catch(response => { | .catch(response => { | ||||
// pid resolving failed | // pid resolving failed | ||||
if (patterns.startsWith('swh:')) { | if (searchQueryText.startsWith('swh:')) { | ||||
// display a useful error message if the input | // display a useful error message if the input | ||||
// looks like a swh pid | // looks like a swh pid | ||||
response.json().then(data => { | response.json().then(data => { | ||||
$('#swh-origin-search-results').hide(); | $('#swh-origin-search-results').hide(); | ||||
$('.swh-search-pagination').hide(); | $('.swh-search-pagination').hide(); | ||||
$('#swh-no-result').text(data.reason); | $('#swh-no-result').text(data.reason); | ||||
$('#swh-no-result').show(); | $('#swh-no-result').show(); | ||||
}); | }); | ||||
} else { | } else { | ||||
// otherwise, proceed with origins search | // otherwise, proceed with origins search | ||||
$('#swh-origin-search-results').show(); | $('#swh-origin-search-results').show(); | ||||
$('.swh-search-pagination').show(); | $('.swh-search-pagination').show(); | ||||
searchOriginsFirst(patterns, limit); | searchOriginsFirst(searchQueryText, limit); | ||||
} | } | ||||
}); | }); | ||||
} | } | ||||
export function initOriginSearch() { | export function initOriginSearch() { | ||||
$(document).ready(() => { | $(document).ready(() => { | ||||
$('#swh-search-origins').submit(event => { | $('#swh-search-origins').submit(event => { | ||||
event.preventDefault(); | event.preventDefault(); | ||||
let patterns = $('#origins-url-patterns').val().trim(); | let searchQueryText = $('#origins-url-patterns').val().trim(); | ||||
let withVisit = $('#swh-search-origins-with-visit').prop('checked'); | let withVisit = $('#swh-search-origins-with-visit').prop('checked'); | ||||
let withContent = $('#swh-filter-empty-visits').prop('checked'); | let withContent = $('#swh-filter-empty-visits').prop('checked'); | ||||
let searchMetadata = $('#swh-search-origin-metadata').prop('checked'); | let searchMetadata = $('#swh-search-origin-metadata').prop('checked'); | ||||
let queryParameters = '?q=' + encodeURIComponent(patterns); | let queryParameters = '?q=' + encodeURIComponent(searchQueryText); | ||||
if (withVisit) { | if (withVisit) { | ||||
queryParameters += '&with_visit'; | queryParameters += '&with_visit'; | ||||
} | } | ||||
if (withContent) { | if (withContent) { | ||||
queryParameters += '&with_content'; | queryParameters += '&with_content'; | ||||
} | } | ||||
if (searchMetadata) { | if (searchMetadata) { | ||||
queryParameters += '&search_metadata'; | queryParameters += '&search_metadata'; | ||||
Show All 38 Lines |