mirror of
https://github.com/simon987/Simple-Incremental-Search-Tool.git
synced 2025-04-18 01:36:49 +00:00
Mime select server-side and must/should toggle for search query
This commit is contained in:
parent
6c7d01dbcb
commit
ba114cfa34
40
run.py
40
run.py
@ -64,7 +64,7 @@ def download(doc_id):
|
|||||||
extension = "" if doc["extension"] is None or doc["extension"] == "" else "." + doc["extension"]
|
extension = "" if doc["extension"] is None or doc["extension"] == "" else "." + doc["extension"]
|
||||||
full_path = os.path.join(directory.path, doc["path"], doc["name"] + extension)
|
full_path = os.path.join(directory.path, doc["path"], doc["name"] + extension)
|
||||||
|
|
||||||
return send_file(full_path)
|
return send_file(full_path, mimetype=doc["mime"])
|
||||||
|
|
||||||
|
|
||||||
@app.route("/thumb/<doc_id>")
|
@app.route("/thumb/<doc_id>")
|
||||||
@ -96,31 +96,9 @@ def thumb(doc_id):
|
|||||||
@app.route("/")
|
@app.route("/")
|
||||||
def search_page():
|
def search_page():
|
||||||
|
|
||||||
mime_map = defaultdict(list)
|
mime_map = search.get_mime_map()
|
||||||
mime_list = []
|
|
||||||
mime_types = search.get_mime_types()
|
|
||||||
|
|
||||||
for mime in mime_types:
|
return render_template("search.html", directories=storage.dirs(), mime_map=mime_map)
|
||||||
splited_mime = os.path.split(mime["key"])
|
|
||||||
mime_map[splited_mime[0]].append(splited_mime[1])
|
|
||||||
|
|
||||||
for mime in mime_map:
|
|
||||||
category = dict()
|
|
||||||
category["text"] = mime
|
|
||||||
|
|
||||||
children = []
|
|
||||||
for m in mime_map[mime]:
|
|
||||||
child = dict()
|
|
||||||
child["text"] = m
|
|
||||||
child["id"] = mime + "/" + m
|
|
||||||
children.append(child)
|
|
||||||
|
|
||||||
if len(children) > 0:
|
|
||||||
category["children"] = children
|
|
||||||
|
|
||||||
mime_list.append(category)
|
|
||||||
|
|
||||||
return render_template("search.html", directories=storage.dirs(), mime_list=mime_list)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/list")
|
@app.route("/list")
|
||||||
@ -128,12 +106,18 @@ def search_liste_page():
|
|||||||
return render_template("searchList.html")
|
return render_template("searchList.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/search")
|
@app.route("/search", methods=['POST'])
|
||||||
def search_route():
|
def search_route():
|
||||||
|
|
||||||
query = request.args.get("q")
|
query = request.json["q"]
|
||||||
query = "" if query is None else query
|
query = "" if query is None else query
|
||||||
page = search.search(query)
|
|
||||||
|
size_min = request.json["size_min"]
|
||||||
|
size_max = request.json["size_max"]
|
||||||
|
mime_types = request.json["mime_types"]
|
||||||
|
must_match = request.json["must_match"]
|
||||||
|
|
||||||
|
page = search.search(query, size_min, size_max, mime_types, must_match)
|
||||||
|
|
||||||
return json.dumps(page)
|
return json.dumps(page)
|
||||||
|
|
||||||
|
60
search.py
60
search.py
@ -1,5 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import elasticsearch
|
import elasticsearch
|
||||||
import requests
|
import requests
|
||||||
from elasticsearch import helpers
|
from elasticsearch import helpers
|
||||||
@ -56,23 +56,65 @@ class Search:
|
|||||||
query = self.es.search(body={
|
query = self.es.search(body={
|
||||||
"aggs": {
|
"aggs": {
|
||||||
"mimeTypes": {
|
"mimeTypes": {
|
||||||
"terms": {"field": "mime_kw"}
|
"terms": {
|
||||||
|
"field": "mime_kw",
|
||||||
|
"size": 10000
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return query["aggregations"]["mimeTypes"]["buckets"]
|
return query["aggregations"]["mimeTypes"]["buckets"]
|
||||||
|
|
||||||
def search(self, query):
|
def get_mime_map(self):
|
||||||
|
|
||||||
|
mime_map = []
|
||||||
|
|
||||||
|
for mime in self.get_mime_types():
|
||||||
|
splited_mime = os.path.split(mime["key"])
|
||||||
|
|
||||||
|
child = dict()
|
||||||
|
child["text"] = splited_mime[1] + " (" + str(mime["doc_count"]) + ")"
|
||||||
|
child["id"] = mime["key"]
|
||||||
|
|
||||||
|
mime_category_exists = False
|
||||||
|
|
||||||
|
for category in mime_map:
|
||||||
|
if category["text"] == splited_mime[0]:
|
||||||
|
category["children"].append(child)
|
||||||
|
mime_category_exists = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not mime_category_exists:
|
||||||
|
mime_map.append({"text": splited_mime[0], "children": [child]})
|
||||||
|
|
||||||
|
return mime_map
|
||||||
|
|
||||||
|
def search(self, query, size_min, size_max, mime_types, must_match):
|
||||||
|
|
||||||
print(query)
|
print(query)
|
||||||
|
print(size_min)
|
||||||
|
print(size_max)
|
||||||
|
|
||||||
page = self.es.search(body={"query":
|
condition = "must" if must_match else "should"
|
||||||
{"multi_match": {
|
|
||||||
"query": query,
|
page = self.es.search(body={
|
||||||
"fields": ["name", "content", "album", "artist", "title", "genre", "album_artist"],
|
"query": {
|
||||||
"operator": "and"
|
"bool": {
|
||||||
}},
|
condition: {
|
||||||
|
"multi_match": {
|
||||||
|
"query": query,
|
||||||
|
"fields": ["name", "content", "album", "artist", "title", "genre",
|
||||||
|
"album_artist"],
|
||||||
|
"operator": "and"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filter": [
|
||||||
|
{"range": {"size": {"gte": size_min, "lte": size_max}}},
|
||||||
|
{"terms": {"mime": mime_types}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"sort": [
|
"sort": [
|
||||||
"_score"
|
"_score"
|
||||||
],
|
],
|
||||||
|
@ -143,6 +143,12 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-xs {
|
||||||
|
padding: .1rem .3rem;
|
||||||
|
font-size: .875rem;
|
||||||
|
border-radius: .2rem;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -153,7 +159,13 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input id="pathBar" type="search" class="form-control" placeholder="Path">
|
<input id="pathBar" type="search" class="form-control" placeholder="Path">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="input-group">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<div class="input-group-text">
|
||||||
|
<span >Must match </span>
|
||||||
|
<input type="checkbox" onclick="toggleSearchBar()" checked>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<input id="searchBar" type="search" class="form-control" placeholder="Search">
|
<input id="searchBar" type="search" class="form-control" placeholder="Search">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -172,7 +184,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<label for="mime">Mime types</label>
|
<label>Mime types</label>
|
||||||
|
|
||||||
|
<button class="btn btn-xs btn-success" onclick="toggleTree()" style="float: right">Toggle</button>
|
||||||
|
|
||||||
<div class="tree"></div>
|
<div class="tree"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -183,14 +197,20 @@
|
|||||||
selection: {
|
selection: {
|
||||||
mode: 'checkbox'
|
mode: 'checkbox'
|
||||||
},
|
},
|
||||||
data: {{ mime_list | tojson }}
|
data: {{ mime_map | tojson }}
|
||||||
});
|
});
|
||||||
new InspireTreeDOM(tree, {
|
new InspireTreeDOM(tree, {
|
||||||
target: '.tree'
|
target: '.tree'
|
||||||
});
|
});
|
||||||
|
|
||||||
//Select all
|
//Select all
|
||||||
tree.select()
|
tree.select();
|
||||||
|
|
||||||
|
tree.on("node.click", function(event, node, handler) {
|
||||||
|
event.preventTreeDefault();
|
||||||
|
handler();
|
||||||
|
searchQueued = true;
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -223,9 +243,28 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
var searchBar = document.getElementById("searchBar");
|
var searchBar = document.getElementById("searchBar");
|
||||||
|
var must_match = true;
|
||||||
var scroll_id = null;
|
var scroll_id = null;
|
||||||
var coolingDown = false;
|
|
||||||
var docCount = 0;
|
var docCount = 0;
|
||||||
|
var treeSelected = false;
|
||||||
|
var searchQueued = false;
|
||||||
|
var coolingDown = false;
|
||||||
|
|
||||||
|
function toggleSearchBar() {
|
||||||
|
must_match = !must_match;
|
||||||
|
searchQueued = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTree() {
|
||||||
|
if (treeSelected) {
|
||||||
|
tree.select();
|
||||||
|
} else {
|
||||||
|
tree.deselect();
|
||||||
|
}
|
||||||
|
|
||||||
|
treeSelected = !treeSelected;
|
||||||
|
searchQueued = true;
|
||||||
|
}
|
||||||
|
|
||||||
function makeStatsCard(searchResult) {
|
function makeStatsCard(searchResult) {
|
||||||
|
|
||||||
@ -566,6 +605,7 @@
|
|||||||
window.addEventListener("scroll", function () {
|
window.addEventListener("scroll", function () {
|
||||||
|
|
||||||
if (!coolingDown) {
|
if (!coolingDown) {
|
||||||
|
|
||||||
var threshold = 200;
|
var threshold = 200;
|
||||||
|
|
||||||
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - threshold) {
|
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - threshold) {
|
||||||
@ -591,9 +631,12 @@
|
|||||||
|
|
||||||
initPopover();
|
initPopover();
|
||||||
|
|
||||||
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);
|
||||||
@ -603,11 +646,25 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getSelectedMimeTypes() {
|
||||||
|
var mimeTypes = [];
|
||||||
|
|
||||||
|
var selected = tree.selected();
|
||||||
|
|
||||||
|
for (var i = 0; i < selected.length; i++) {
|
||||||
|
//Only get children
|
||||||
|
if (selected[i].text.indexOf("(") !== -1) {
|
||||||
|
mimeTypes.push(selected[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mimeTypes
|
||||||
|
}
|
||||||
|
|
||||||
function search() {
|
function search() {
|
||||||
if (!coolingDown) {
|
|
||||||
|
|
||||||
coolingDown = true;
|
if (searchQueued === true) {
|
||||||
|
searchQueued = false;
|
||||||
|
|
||||||
//Clear old search results
|
//Clear old search results
|
||||||
var searchResults = document.getElementById("searchResults");
|
var searchResults = document.getElementById("searchResults");
|
||||||
@ -617,8 +674,6 @@
|
|||||||
|
|
||||||
var query = searchBar.value;
|
var query = searchBar.value;
|
||||||
|
|
||||||
console.log("query: " + query);
|
|
||||||
|
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
if (this.readyState === 4 && this.status === 200) {
|
if (this.readyState === 4 && this.status === 200) {
|
||||||
@ -648,25 +703,32 @@
|
|||||||
|
|
||||||
//Initialise download/view button popover
|
//Initialise download/view button popover
|
||||||
initPopover();
|
initPopover();
|
||||||
|
|
||||||
window.setTimeout(function() {
|
|
||||||
coolingDown = false;
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/search?q=" + query, true);
|
|
||||||
xhttp.send();
|
xhttp.open("POST", "/search", true);
|
||||||
|
|
||||||
|
var postBody = {};
|
||||||
|
postBody.q = query;
|
||||||
|
postBody.size_min = size_min;
|
||||||
|
postBody.size_max = size_max;
|
||||||
|
postBody.mime_types = getSelectedMimeTypes();
|
||||||
|
postBody.must_match = must_match;
|
||||||
|
xhttp.setRequestHeader('content-type', 'application/json');
|
||||||
|
xhttp.send(JSON.stringify(postBody));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pathAutoComplete;
|
var pathAutoComplete;
|
||||||
|
var size_min = 0;
|
||||||
|
var size_max = 10000000000000;
|
||||||
|
|
||||||
searchBar.addEventListener("keyup", function () {
|
searchBar.addEventListener("keyup", function () {
|
||||||
search();
|
searchQueued = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
//Size slider
|
//Size slider
|
||||||
$("#sizeSlider").ionRangeSlider({
|
var sizeSlider = $("#sizeSlider").ionRangeSlider({
|
||||||
type: "double",
|
type: "double",
|
||||||
grid: false,
|
grid: false,
|
||||||
force_edges: true,
|
force_edges: true,
|
||||||
@ -687,12 +749,16 @@
|
|||||||
return humanFileSize(num * num * num)
|
return humanFileSize(num * num * num)
|
||||||
},
|
},
|
||||||
onChange: function(e) {
|
onChange: function(e) {
|
||||||
var from = (e.from * e.from * e.from);
|
size_min = (e.from * e.from * e.from);
|
||||||
var to = (e.to * e.to * e.to);
|
size_max = (e.to * e.to * e.to);
|
||||||
|
|
||||||
search();
|
if (e.to >= 3684) {
|
||||||
|
size_max = 10000000000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchQueued = true;
|
||||||
}
|
}
|
||||||
});
|
})[0];
|
||||||
|
|
||||||
//Directories select
|
//Directories select
|
||||||
document.getElementById("directories").addEventListener("change", function () {
|
document.getElementById("directories").addEventListener("change", function () {
|
||||||
@ -701,20 +767,10 @@
|
|||||||
$(selectedDirs).each(function(){
|
$(selectedDirs).each(function(){
|
||||||
selected.push($(this).val());
|
selected.push($(this).val());
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(selected);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Mime types select
|
window.setInterval(search, 75)
|
||||||
document.getElementById("mime").addEventListener("change", function () {
|
|
||||||
var selectedMimes = $('#mime').find('option:selected');
|
|
||||||
var selected = [];
|
|
||||||
$(selectedMimes).each(function(){
|
|
||||||
selected.push($(this).val());
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(selected);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user