diff --git a/app.py b/app.py index 1044dc0..9acbef0 100644 --- a/app.py +++ b/app.py @@ -10,6 +10,7 @@ import config from flask_caching import Cache from task import TaskDispatcher, Task, CrawlServer from search.search import ElasticSearchEngine +from jinja2 import Undefined app = Flask(__name__) recaptcha = ReCaptcha(app=app, @@ -239,9 +240,27 @@ def search(): size_max = request.args.get("size_max") if "size_max" in request.args else "size_max" size_max = int(size_max) if size_max.isdigit() else 0 + match_all = "all" in request.args + + field_name = "field_name" in request.args + field_trigram = "field_trigram" in request.args + field_path = "field_path" in request.args + + if not field_name and not field_trigram and not field_path: + # If no fields are selected, search in all + field_name = field_path = field_trigram = True + + fields = [] + if field_path: + fields.append("path") + if field_name: + fields.append("name^5") + if field_trigram: + fields.append("name.nGram^2") + if len(q) >= 3: try: - hits = searchEngine.search(q, page, per_page, sort_order, extensions, size_min, size_max) + hits = searchEngine.search(q, page, per_page, sort_order, extensions, size_min, size_max, match_all, fields) hits = db.join_website_on_search_result(hits) except InvalidQueryException as e: flash("Invalid query: " + str(e), "warning") @@ -250,9 +269,15 @@ def search(): hits = None return render_template("search.html", - results=hits, q=q, p=page, sort_order=sort_order, - per_page=per_page, results_set=config.RESULTS_PER_PAGE, - extensions=",".join(extensions), size_min=size_min, size_max=size_max) + results=hits, + q=q, + p=page, per_page=per_page, + sort_order=sort_order, + results_set=config.RESULTS_PER_PAGE, + extensions=",".join(extensions), + size_min=size_min, size_max=size_max, + match_all=match_all, + field_trigram=field_trigram, field_path=field_path, field_name=field_name) @app.route("/contribute") diff --git a/search/search.py b/search/search.py index 385c027..f2102d8 100644 --- a/search/search.py +++ b/search/search.py @@ -16,7 +16,7 @@ class SearchEngine: def import_json(self, in_str: str, website_id: int): raise NotImplementedError - def search(self, query, page, per_page, sort_order, extension, size_min, size_max) -> {}: + def search(self, query, page, per_page, sort_order, extension, size_min, size_max, match_all, fields) -> {}: raise NotImplementedError def reset(self): @@ -142,7 +142,7 @@ class ElasticSearchEngine(SearchEngine): action_string = '{"index":{}}\n' return "\n".join("".join([action_string, ujson.dumps(doc)]) for doc in docs) - def search(self, query, page, per_page, sort_order, extensions, size_min, size_max) -> {}: + def search(self, query, page, per_page, sort_order, extensions, size_min, size_max, match_all, fields) -> {}: filters = [] if extensions: @@ -167,8 +167,8 @@ class ElasticSearchEngine(SearchEngine): "must": { "multi_match": { "query": query, - "fields": ["name^5", "name.nGram^2", "path"], - "operator": "or" + "fields": fields, + "operator": "or" if match_all else "and" } }, "filter": filters diff --git a/static/css/main.css b/static/css/main.css index 54d5141..0d858ad 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -92,8 +92,8 @@ mark { background-color: rgba(255, 255, 0, 0.4); - border-radius: 2px; - padding: 1px; + border-radius: 0; + padding: 1px 0; } body { color: #BBBBBB; diff --git a/templates/search.html b/templates/search.html index 212c61f..a4046df 100644 --- a/templates/search.html +++ b/templates/search.html @@ -14,13 +14,59 @@
{# Query #} -
+
+
+
+ + +
+
- {# Sort order #} +
+ {# Size #} +
File size
+ + + + +
+ {# File extension #} +
+
File extension
+
+
+
.
+
+ +
+
+ {# Fields #} +
+
Search in
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
Display options
+
+
+ {# Sort order #}
-
- {# Filters #} - Filters -
- {# File extension #} -
-
-
-
.
-
- -
+ {# Search button #} +
+
- {# Size #} - - - - -
@@ -76,7 +107,14 @@ {% for hit in results["hits"]["hits"] %} {% set src = hit["_source"] %} - {% set hl_name = hit["highlight"]["name"][0] if "name" in hit["highlight"] else src["name"] %} + {% if "name" in hit["highlight"] %} + {% set hl_name = hit["highlight"]["name"][0] %} + {% elif "name.nGram" in hit["highlight"] %} + {% set hl_name = hit["highlight"]["name.nGram"][0] %} + {% else %} + {% set hl_name = src["name"] %} + {% endif %} + {% set hl_path = hit["highlight"]["path"][0] if "path" in hit["highlight"] else src["path"] %} @@ -98,7 +136,8 @@ {% endif %} {# File path #}
- {{ src["website_url"] }}{{ hl_path|safe }} + {{ src["website_url"] }}{{ hl_path|safe }}
{# File size & date #} @@ -112,11 +151,11 @@
{% if results["hits"]["total"] > (p + 1) * per_page %} - Next {% endif %} {% if p > 0 %} - Previous {% endif %} @@ -151,7 +190,7 @@ drag_interval: true, prettify: function (num) { - if(num === 0) { + if (num === 0) { return "0 B" } else if (num >= 3684) { return humanFileSize(num * num * num) + "+"; @@ -159,11 +198,11 @@ return humanFileSize(num * num * num) }, - onFinish: function(e) { + onFinish: function (e) { let size_min = (e.from * e.from * e.from); let size_max = (e.to * e.to * e.to); - if (e.to >= 3684) { + if (e.to >= 3684) { size_max = null; }