Search by path

This commit is contained in:
simon987 2018-04-15 20:53:05 -04:00
parent ba114cfa34
commit b454653d51
5 changed files with 181 additions and 127 deletions

View File

@ -68,7 +68,7 @@ class Indexer:
"analysis": {"tokenizer": {"my_nGram_tokenizer": {"type": "nGram", "min_gram": 3, "max_gram": 3}}}}, "analysis": {"tokenizer": {"my_nGram_tokenizer": {"type": "nGram", "min_gram": 3, "max_gram": 3}}}},
index=self.index_name) index=self.index_name)
self.es.indices.put_settings(body={ self.es.indices.put_settings(body={
"analysis": {"analyzer": {"path_analyser": {"tokenizer": "path_tokenizer"}}}}, "analysis": {"analyzer": {"path_analyser": {"tokenizer": "path_tokenizer", "filter": ["lowercase"]}}}},
index=self.index_name) index=self.index_name)
self.es.indices.put_settings(body={ self.es.indices.put_settings(body={
"analysis": {"analyzer": {"my_nGram": {"tokenizer": "my_nGram_tokenizer", "filter": ["lowercase", "analysis": {"analyzer": {"my_nGram": {"tokenizer": "my_nGram_tokenizer", "filter": ["lowercase",
@ -80,7 +80,7 @@ class Indexer:
"suggest-path": {"type": "completion", "analyzer": "keyword"}, "suggest-path": {"type": "completion", "analyzer": "keyword"},
"mime": {"type": "text", "analyzer": "path_analyser", "copy_to": "mime_kw"}, "mime": {"type": "text", "analyzer": "path_analyser", "copy_to": "mime_kw"},
"mime_kw": {"type": "keyword"}, "mime_kw": {"type": "keyword"},
"directory": {"type": "keyword"}, "directory": {"type": "short"},
"name": {"analyzer": "my_nGram", "type": "text"}, "name": {"analyzer": "my_nGram", "type": "text"},
"album": {"analyzer": "my_nGram", "type": "text"}, "album": {"analyzer": "my_nGram", "type": "text"},
"artist": {"analyzer": "my_nGram", "type": "text"}, "artist": {"analyzer": "my_nGram", "type": "text"},

13
run.py
View File

@ -8,7 +8,6 @@ import humanfriendly
from search import Search from search import Search
from PIL import Image from PIL import Image
from io import BytesIO from io import BytesIO
from collections import defaultdict
app = Flask(__name__) app = Flask(__name__)
app.secret_key = "A very secret key" app.secret_key = "A very secret key"
@ -18,8 +17,6 @@ tm = TaskManager(storage)
search = Search("changeme") search = Search("changeme")
def get_dir_size(path): def get_dir_size(path):
size = 0 size = 0
@ -33,6 +30,12 @@ def get_dir_size(path):
return size return size
@app.route("/suggest")
def suggest():
return json.dumps(search.suggest(request.args.get("prefix")))
@app.route("/document/<doc_id>") @app.route("/document/<doc_id>")
def document(doc_id): def document(doc_id):
@ -116,8 +119,10 @@ def search_route():
size_max = request.json["size_max"] size_max = request.json["size_max"]
mime_types = request.json["mime_types"] mime_types = request.json["mime_types"]
must_match = request.json["must_match"] must_match = request.json["must_match"]
directories = request.json["directories"] # todo: make sure dir exists and is enabled
path = request.json["path"]
page = search.search(query, size_min, size_max, mime_types, must_match) page = search.search(query, size_min, size_max, mime_types, must_match, directories, path)
return json.dumps(page) return json.dumps(page)

View File

@ -90,13 +90,19 @@ class Search:
return mime_map return mime_map
def search(self, query, size_min, size_max, mime_types, must_match): def search(self, query, size_min, size_max, mime_types, must_match, directories, path):
print(query)
print(size_min)
print(size_max)
condition = "must" if must_match else "should" condition = "must" if must_match else "should"
print(directories)
filters = [
{"range": {"size": {"gte": size_min, "lte": size_max}}},
{"terms": {"mime": mime_types}},
{"terms": {"directory": directories}}
]
if path != "":
filters.append({"term": {"path": path}})
page = self.es.search(body={ page = self.es.search(body={
"query": { "query": {
@ -109,10 +115,7 @@ class Search:
"operator": "and" "operator": "and"
} }
}, },
"filter": [ "filter": filters
{"range": {"size": {"gte": size_min, "lte": size_max}}},
{"terms": {"mime": mime_types}}
]
} }
}, },
"sort": [ "sort": [
@ -124,16 +127,6 @@ class Search:
"name": {"pre_tags": ["<span class='hl'>"], "post_tags": ["</span>"]}, "name": {"pre_tags": ["<span class='hl'>"], "post_tags": ["</span>"]},
} }
}, },
"suggest": {
"path": {
"prefix": query,
"completion": {
"field": "suggest-path",
"skip_duplicates": True,
"size": 4000
}
}
},
"aggs": { "aggs": {
"total_size": {"sum": {"field": "size"}} "total_size": {"sum": {"field": "size"}}
}, },
@ -141,6 +134,28 @@ class Search:
return page return page
def suggest(self, prefix):
suggestions = self.es.search(body={
"suggest": {
"path": {
"prefix": prefix,
"completion": {
"field": "suggest-path",
"skip_duplicates": True,
"size": 10000
}
}
}
})
path_list = []
for option in suggestions["suggest"]["path"][0]["options"]:
path_list.append(option["_source"]["path"])
return path_list
def scroll(self, scroll_id): def scroll(self, scroll_id):
page = self.es.scroll(scroll_id=scroll_id, scroll="3m") page = self.es.scroll(scroll_id=scroll_id, scroll="3m")

View File

@ -7,6 +7,7 @@
{% block body %} {% block body %}
<style> <style>
body {overflow-y:scroll;}
.document { .document {
padding: 0.5rem; padding: 0.5rem;
} }
@ -44,8 +45,6 @@
background-color: #FAAB3C; background-color: #FAAB3C;
} }
.card-img-top { .card-img-top {
display: block; display: block;
min-width: 64px; min-width: 64px;
@ -80,8 +79,11 @@
.fit { .fit {
width: 100%; width: 100%;
height: 100%; height: 100%;
margin-top: 3px; {# margin-top: 3px;#}
padding: 3px; padding: 3px;
min-width: 64px;
max-width: 100%;
max-height: 256px;
} }
@media (min-width: 1200px) { @media (min-width: 1200px) {
@ -162,8 +164,8 @@
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span >Must match&nbsp</span> <span onclick="document.getElementById('barToggle').click()">Must match&nbsp</span>
<input type="checkbox" onclick="toggleSearchBar()" checked> <input type="checkbox" id="barToggle" onclick="toggleSearchBar()" checked>
</div> </div>
</div> </div>
<input id="searchBar" type="search" class="form-control" placeholder="Search"> <input id="searchBar" type="search" class="form-control" placeholder="Search">
@ -178,7 +180,9 @@
<select class="custom-select" id="directories" multiple size="6"> <select class="custom-select" id="directories" multiple size="6">
{% for dir_id in directories %} {% for dir_id in directories %}
<option selected value="{{ directories[dir_id].id }}">{{ directories[dir_id].name }}</option> {% if directories[dir_id].enabled %}
<option selected value="{{ directories[dir_id].id }}">{{ directories[dir_id].name }}</option>
{% endif %}
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
@ -193,7 +197,7 @@
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
var tree = new InspireTree({ let tree = new InspireTree({
selection: { selection: {
mode: 'checkbox' mode: 'checkbox'
}, },
@ -221,17 +225,25 @@
new autoComplete({ new autoComplete({
selector: '#pathBar', selector: '#pathBar',
minChars: 1, minChars: 1,
source: function(term, suggest) { delay: 75,
renderItem: function (item, search){
return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item + '</div>';
},
source: async function(term, suggest) {
term = term.toLowerCase(); term = term.toLowerCase();
var choices = pathAutoComplete;
var matches = []; const choices = await getPathChoices();
for (var i=0; i<choices.length; i++) {
let matches = [];
for (let i=0; i<choices.length; i++) {
if (~choices[i].toLowerCase().indexOf(term)) { if (~choices[i].toLowerCase().indexOf(term)) {
matches.push(choices[i]); matches.push(choices[i]);
} }
} }
suggest(matches); suggest(matches);
},
onSelect: function(event, term, item) {
searchQueued = true;
} }
}); });
</script> </script>
@ -242,13 +254,15 @@
<script> <script>
var searchBar = document.getElementById("searchBar"); let searchBar = document.getElementById("searchBar");
var must_match = true; let pathBar = document.getElementById("pathBar");
var scroll_id = null; let must_match = true;
var docCount = 0; let scroll_id = null;
var treeSelected = false; let docCount = 0;
var searchQueued = false; let treeSelected = false;
var coolingDown = false; let searchQueued = false;
let coolingDown = false;
let selectedDirs = [];
function toggleSearchBar() { function toggleSearchBar() {
must_match = !must_match; must_match = !must_match;
@ -268,15 +282,15 @@
function makeStatsCard(searchResult) { function makeStatsCard(searchResult) {
var statsCard = document.createElement("div"); let statsCard = document.createElement("div");
statsCard.setAttribute("class", "card"); statsCard.setAttribute("class", "card");
var statsCardBody = document.createElement("div"); let statsCardBody = document.createElement("div");
statsCardBody.setAttribute("class", "card-body"); statsCardBody.setAttribute("class", "card-body");
var stat = document.createElement("p"); let stat = document.createElement("p");
stat.appendChild(document.createTextNode(searchResult["hits"]["total"] + " results in " + searchResult["took"] + "ms")); stat.appendChild(document.createTextNode(searchResult["hits"]["total"] + " results in " + searchResult["took"] + "ms"));
var sizeStat = document.createElement("span"); let sizeStat = document.createElement("span");
sizeStat.appendChild(document.createTextNode(humanFileSize(searchResult["aggregations"]["total_size"]["value"]))); sizeStat.appendChild(document.createTextNode(humanFileSize(searchResult["aggregations"]["total_size"]["value"])));
statsCardBody.appendChild(stat); statsCardBody.appendChild(stat);
@ -287,7 +301,7 @@
} }
function makeResultContainer() { function makeResultContainer() {
var resultContainer = document.createElement("div"); let resultContainer = document.createElement("div");
resultContainer.setAttribute("class", "card-columns"); resultContainer.setAttribute("class", "card-columns");
return resultContainer; return resultContainer;
@ -302,12 +316,12 @@
return "? B" return "? B"
} }
var thresh = 1000; let thresh = 1000;
if(Math.abs(bytes) < thresh) { if(Math.abs(bytes) < thresh) {
return bytes + ' B'; return bytes + ' B';
} }
var units = ['kB','MB','GB','TB','PB','EB','ZB','YB']; let units = ['kB','MB','GB','TB','PB','EB','ZB','YB'];
var u = -1; let u = -1;
do { do {
bytes /= thresh; bytes /= thresh;
++u; ++u;
@ -332,7 +346,7 @@
* @param documentId * @param documentId
*/ */
function gifOver(thumbnail, documentId) { function gifOver(thumbnail, documentId) {
var callee = arguments.callee; let callee = arguments.callee;
thumbnail.addEventListener("mouseover", function () { thumbnail.addEventListener("mouseover", function () {
@ -357,37 +371,34 @@
}) })
} }
function videoOver(thumbnail, imgWrapper, thumbnailOverlay, documentId) { function videoOver(thumbnail, imgWrapper, thumbnailOverlay, documentId, docCard) {
thumbnail.addEventListener("mouseover", function () {
this.mouseStayedOver = true; docCard.addEventListener("focus", function () {
let callee = arguments.callee;
docCard.mouseStayedOver = true;
window.setTimeout(function() { window.setTimeout(function() {
if(thumbnail.mouseStayedOver) {
if(docCard.mouseStayedOver) {
docCard.removeEventListener('focus', callee, false);
imgWrapper.removeChild(thumbnail); imgWrapper.removeChild(thumbnail);
imgWrapper.removeChild(thumbnailOverlay); imgWrapper.removeChild(thumbnailOverlay);
var video = document.createElement("video"); let video = document.createElement("video");
var vidSource = document.createElement("source"); let vidSource = document.createElement("source");
vidSource.setAttribute("src", "/file/" + documentId); vidSource.setAttribute("src", "/file/" + documentId);
vidSource.setAttribute("type", "video/webm"); vidSource.setAttribute("type", "video/webm");
video.appendChild(vidSource); video.appendChild(vidSource);
video.setAttribute("class", "fit"); video.setAttribute("class", "fit");
video.setAttribute("loop", "");
video.setAttribute("controls", "");
video.setAttribute("preload", "");
video.setAttribute("poster", "/thumb/" + documentId); video.setAttribute("poster", "/thumb/" + documentId);
imgWrapper.appendChild(video); imgWrapper.appendChild(video);
//Video hover docCard.addEventListener("blur", function() {
video.addEventListener("mouseover", function() {
var isPlaying = video.currentTime > 0 && !video.paused && !video.ended && video.readyState > 2;
if (!isPlaying) {
video.play();
}
});
video.addEventListener("mouseout", function() {
video.currentTime = 0;
video.pause(); video.pause();
}); });
@ -397,8 +408,8 @@
} }
}, 750); }, 750);
}); });
thumbnail.addEventListener("mouseout", function() { docCard.addEventListener("blur", function() {
this.mouseStayedOver = false; docCard.mouseStayedOver = false;
}); });
} }
@ -412,7 +423,7 @@
}); });
} }
var counter = 0; let counter = 0;
/** /**
* *
* @param hit * @param hit
@ -420,21 +431,21 @@
*/ */
function createDocCard(hit) { function createDocCard(hit) {
var docCard = document.createElement("div"); let docCard = document.createElement("div");
docCard.setAttribute("class", "card"); docCard.setAttribute("class", "card");
docCard.setAttribute("tabindex", "-1"); docCard.setAttribute("tabindex", "-1");
var docCardBody = document.createElement("div"); let docCardBody = document.createElement("div");
docCardBody.setAttribute("class", "card-body document"); docCardBody.setAttribute("class", "card-body document");
var link = document.createElement("a"); let link = document.createElement("a");
link.setAttribute("href", "/document/" + hit["_id"]); link.setAttribute("href", "/document/" + hit["_id"]);
link.setAttribute("target", "_blank"); link.setAttribute("target", "_blank");
//Title //Title
var title = document.createElement("p"); let title = document.createElement("p");
title.setAttribute("class", "file-title"); title.setAttribute("class", "file-title");
var extension = hit["_source"].hasOwnProperty("extension") && hit["_source"]["extension"] !== "" ? "." + hit["_source"]["extension"] : ""; let extension = hit["_source"].hasOwnProperty("extension") && hit["_source"]["extension"] !== "" ? "." + hit["_source"]["extension"] : "";
if (hit.hasOwnProperty("highlight") && hit["highlight"].hasOwnProperty("name")) { if (hit.hasOwnProperty("highlight") && hit["highlight"].hasOwnProperty("name")) {
title.insertAdjacentHTML('afterbegin', hit["highlight"]["name"] + extension); title.insertAdjacentHTML('afterbegin', hit["highlight"]["name"] + extension);
@ -445,18 +456,18 @@
title.setAttribute("title", hit["_source"]["path"] + hit["_source"]["name"] + extension); title.setAttribute("title", hit["_source"]["path"] + hit["_source"]["name"] + extension);
docCard.appendChild(title); docCard.appendChild(title);
var tagContainer = document.createElement("div"); let tagContainer = document.createElement("div");
tagContainer.setAttribute("class", "card-text"); tagContainer.setAttribute("class", "card-text");
if (hit["_source"].hasOwnProperty("mime") && hit["_source"]["mime"] !== null) { if (hit["_source"].hasOwnProperty("mime") && hit["_source"]["mime"] !== null) {
var tags = []; let tags = [];
var thumbnail = null; let thumbnail = null;
var thumbnailOverlay = null; let thumbnailOverlay = null;
var imgWrapper = document.createElement("div"); let imgWrapper = document.createElement("div");
imgWrapper.setAttribute("style", "position: relative"); imgWrapper.setAttribute("style", "position: relative");
var mimeCategory = hit["_source"]["mime"].split("/")[0]; let mimeCategory = hit["_source"]["mime"].split("/")[0];
//Thumbnail //Thumbnail
switch (mimeCategory) { switch (mimeCategory) {
@ -477,7 +488,7 @@
thumbnailOverlay.setAttribute("class", "card-img-overlay"); thumbnailOverlay.setAttribute("class", "card-img-overlay");
//Resolution //Resolution
var resolutionBadge = document.createElement("span"); let resolutionBadge = document.createElement("span");
resolutionBadge.setAttribute("class", "badge badge-resolution"); resolutionBadge.setAttribute("class", "badge badge-resolution");
if (hit["_source"].hasOwnProperty("width")) { if (hit["_source"].hasOwnProperty("width")) {
resolutionBadge.appendChild(document.createTextNode(hit["_source"]["width"] + "x" + hit["_source"]["height"])); resolutionBadge.appendChild(document.createTextNode(hit["_source"]["width"] + "x" + hit["_source"]["height"]));
@ -497,13 +508,13 @@
thumbnailOverlay.setAttribute("class", "card-img-overlay"); thumbnailOverlay.setAttribute("class", "card-img-overlay");
//Duration //Duration
var durationBadge = document.createElement("span"); let durationBadge = document.createElement("span");
durationBadge.setAttribute("class", "badge badge-resolution"); durationBadge.setAttribute("class", "badge badge-resolution");
durationBadge.appendChild(document.createTextNode(parseFloat(hit["_source"]["duration"]).toFixed(2) + "s")); durationBadge.appendChild(document.createTextNode(parseFloat(hit["_source"]["duration"]).toFixed(2) + "s"));
thumbnailOverlay.appendChild(durationBadge); thumbnailOverlay.appendChild(durationBadge);
//Hover //Hover
videoOver(thumbnail, imgWrapper, thumbnailOverlay, hit["_id"]) videoOver(thumbnail, imgWrapper, thumbnailOverlay, hit["_id"], docCard)
} }
@ -511,13 +522,16 @@
switch (mimeCategory) { switch (mimeCategory) {
case "video": case "video":
var formatTag = document.createElement("span"); if (hit["_source"].hasOwnProperty("format_long_name")) {
formatTag.setAttribute("class", "badge badge-pill badge-video"); let formatTag = document.createElement("span");
formatTag.appendChild(document.createTextNode(hit["_source"]["format_long_name"].replace(" ", ""))); formatTag.setAttribute("class", "badge badge-pill badge-video");
tags.push(formatTag); formatTag.appendChild(document.createTextNode(hit["_source"]["format_long_name"].replace(" ", "")));
tags.push(formatTag);
}
break; break;
case "image": case "image":
formatTag = document.createElement("span"); formatTag = document.createElement("span");
formatTag.setAttribute("class", "badge badge-pill badge-image"); formatTag.setAttribute("class", "badge badge-pill badge-image");
formatTag.appendChild(document.createTextNode(format)); formatTag.appendChild(document.createTextNode(format));
@ -543,7 +557,7 @@
//Content //Content
if (hit.hasOwnProperty("highlight") && hit["highlight"].hasOwnProperty("content")) { if (hit.hasOwnProperty("highlight") && hit["highlight"].hasOwnProperty("content")) {
var contentDiv = document.createElement("div"); let contentDiv = document.createElement("div");
contentDiv.setAttribute("class", "content-div bg-light"); contentDiv.setAttribute("class", "content-div bg-light");
contentDiv.insertAdjacentHTML('afterbegin', hit["highlight"]["content"][0]); contentDiv.insertAdjacentHTML('afterbegin', hit["highlight"]["content"][0]);
docCard.appendChild(contentDiv); docCard.appendChild(contentDiv);
@ -562,7 +576,7 @@
imgWrapper.appendChild(thumbnailOverlay); imgWrapper.appendChild(thumbnailOverlay);
} }
for (var i = 0; i < tags.length; i++) { for (let i = 0; i < tags.length; i++) {
tagContainer.appendChild(tags[i]); tagContainer.appendChild(tags[i]);
} }
@ -570,7 +584,7 @@
} }
//Size tag //Size tag
var sizeTag = document.createElement("small"); let sizeTag = document.createElement("small");
sizeTag.appendChild(document.createTextNode(humanFileSize(hit["_source"]["size"]))); sizeTag.appendChild(document.createTextNode(humanFileSize(hit["_source"]["size"])));
sizeTag.setAttribute("class", "text-muted"); sizeTag.setAttribute("class", "text-muted");
tagContainer.appendChild(sizeTag); tagContainer.appendChild(sizeTag);
@ -589,14 +603,14 @@
} }
function makePageIndicator(searchResult) { function makePageIndicator(searchResult) {
var pageIndicator = document.createElement("div"); let pageIndicator = document.createElement("div");
pageIndicator.appendChild(document.createTextNode(docCount + " / " +searchResult["hits"]["total"])); pageIndicator.appendChild(document.createTextNode(docCount + " / " +searchResult["hits"]["total"]));
return pageIndicator; return pageIndicator;
} }
function insertHits(resultContainer, hits) { function insertHits(resultContainer, hits) {
for (var i = 0 ; i < hits.length; i++) { for (let i = 0 ; i < hits.length; i++) {
resultContainer.appendChild(createDocCard(hits[i])); resultContainer.appendChild(createDocCard(hits[i]));
docCount++; docCount++;
} }
@ -606,25 +620,25 @@
if (!coolingDown) { if (!coolingDown) {
var threshold = 200; let threshold = 350;
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - threshold) { if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - threshold) {
//load next page //load next page
var xhttp = new XMLHttpRequest(); let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() { xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) { if (this.readyState === 4 && this.status === 200) {
var searchResult = JSON.parse(this.responseText); let searchResult = JSON.parse(this.responseText);
var searchResults = document.getElementById("searchResults"); let searchResults = document.getElementById("searchResults");
var hits = searchResult["hits"]["hits"]; let hits = searchResult["hits"]["hits"];
//Page indicator //Page indicator
var pageIndicator = makePageIndicator(searchResult); let pageIndicator = makePageIndicator(searchResult);
searchResults.appendChild(pageIndicator); searchResults.appendChild(pageIndicator);
//Result container //Result container
var resultContainer = makeResultContainer(); let resultContainer = makeResultContainer();
searchResults.appendChild(resultContainer); searchResults.appendChild(resultContainer);
insertHits(resultContainer, hits); insertHits(resultContainer, hits);
@ -634,9 +648,6 @@
if (hits.length !== 0) { if (hits.length !== 0) {
coolingDown = false; coolingDown = false;
} }
console.log(hits.length)
} }
}; };
xhttp.open("GET", "/scroll?scroll_id=" + scroll_id, true); xhttp.open("GET", "/scroll?scroll_id=" + scroll_id, true);
@ -647,11 +658,11 @@
}); });
function getSelectedMimeTypes() { function getSelectedMimeTypes() {
var mimeTypes = []; let mimeTypes = [];
var selected = tree.selected(); let selected = tree.selected();
for (var i = 0; i < selected.length; i++) { for (let i = 0; i < selected.length; i++) {
//Only get children //Only get children
if (selected[i].text.indexOf("(") !== -1) { if (selected[i].text.indexOf("(") !== -1) {
mimeTypes.push(selected[i].id); mimeTypes.push(selected[i].id);
@ -667,18 +678,18 @@
searchQueued = false; searchQueued = false;
//Clear old search results //Clear old search results
var searchResults = document.getElementById("searchResults"); let searchResults = document.getElementById("searchResults");
while (searchResults.firstChild) { while (searchResults.firstChild) {
searchResults.removeChild(searchResults.firstChild); searchResults.removeChild(searchResults.firstChild);
} }
var query = searchBar.value; let query = searchBar.value;
var xhttp = new XMLHttpRequest(); let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() { xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) { if (this.readyState === 4 && this.status === 200) {
var searchResult = JSON.parse(this.responseText); let searchResult = JSON.parse(this.responseText);
scroll_id = searchResult["_scroll_id"]; scroll_id = searchResult["_scroll_id"];
//Search stats //Search stats
@ -687,14 +698,14 @@
//Autocomplete //Autocomplete
if (searchResult.hasOwnProperty("suggest") && searchResult["suggest"].hasOwnProperty("path")) { if (searchResult.hasOwnProperty("suggest") && searchResult["suggest"].hasOwnProperty("path")) {
pathAutoComplete = []; pathAutoComplete = [];
for (var i = 0; i < searchResult["suggest"]["path"][0]["options"].length; i++) { for (let i = 0; i < searchResult["suggest"]["path"][0]["options"].length; i++) {
pathAutoComplete.push(searchResult["suggest"]["path"][0]["options"][i].text) pathAutoComplete.push(searchResult["suggest"]["path"][0]["options"][i].text)
} }
} }
//Setup page //Setup page
var resultContainer = makeResultContainer(); let resultContainer = makeResultContainer();
searchResults.appendChild(resultContainer); searchResults.appendChild(resultContainer);
//Insert search results (hits) //Insert search results (hits)
@ -708,27 +719,29 @@
xhttp.open("POST", "/search", true); xhttp.open("POST", "/search", true);
var postBody = {}; let postBody = {};
postBody.q = query; postBody.q = query;
postBody.size_min = size_min; postBody.size_min = size_min;
postBody.size_max = size_max; postBody.size_max = size_max;
postBody.mime_types = getSelectedMimeTypes(); postBody.mime_types = getSelectedMimeTypes();
postBody.must_match = must_match; postBody.must_match = must_match;
postBody.directories = selectedDirs;
postBody.path = pathBar.value.replace(/\/$/, ""); //remove trailing slashes
xhttp.setRequestHeader('content-type', 'application/json'); xhttp.setRequestHeader('content-type', 'application/json');
xhttp.send(JSON.stringify(postBody)); xhttp.send(JSON.stringify(postBody));
} }
} }
var pathAutoComplete; let pathAutoComplete = [];
var size_min = 0; let size_min = 0;
var size_max = 10000000000000; let size_max = 10000000000000;
searchBar.addEventListener("keyup", function () { searchBar.addEventListener("keyup", function () {
searchQueued = true; searchQueued = true;
}); });
//Size slider //Size slider
var sizeSlider = $("#sizeSlider").ionRangeSlider({ let sizeSlider = $("#sizeSlider").ionRangeSlider({
type: "double", type: "double",
grid: false, grid: false,
force_edges: true, force_edges: true,
@ -761,13 +774,34 @@
})[0]; })[0];
//Directories select //Directories select
document.getElementById("directories").addEventListener("change", function () { function updateDirectories() {
var selectedDirs = $('#directories').find('option:selected'); let selected = $('#directories').find('option:selected');
var selected = []; selectedDirs = [];
$(selectedDirs).each(function(){ $(selected).each(function(){
selected.push($(this).val()); selectedDirs.push(parseInt($(this).val()));
}); });
});
searchQueued = true;
}
document.getElementById("directories").addEventListener("change", updateDirectories);
updateDirectories();
searchQueued = false;
//Suggest
function getPathChoices() {
return new Promise(getPaths => {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
getPaths(JSON.parse(xhttp.responseText))
}
};
xhttp.open("GET", "/suggest?prefix=" + pathBar.value, true);
xhttp.send();
});
}
window.setInterval(search, 75) window.setInterval(search, 75)

View File

@ -21,8 +21,8 @@ class ThumbnailGenerator:
try: try:
self.generate_image(path, dest_path) self.generate_image(path, dest_path)
except OSError: except Exception:
print("Not an image " + path) print("Couldn't make thumbnail for " + path)
elif mime.startswith("video"): elif mime.startswith("video"):
try: try: