2018-11-08 19:45:21 +00:00
|
|
|
from django.db.models import Q
|
2021-07-07 17:57:04 -05:00
|
|
|
from django.conf import settings
|
|
|
|
|
2020-01-08 13:29:58 -06:00
|
|
|
from peeringdb_server.models import (
|
|
|
|
InternetExchange,
|
|
|
|
Network,
|
|
|
|
Facility,
|
|
|
|
Organization,
|
|
|
|
)
|
2021-07-07 17:57:04 -05:00
|
|
|
|
|
|
|
# import time
|
2019-05-02 15:20:20 +00:00
|
|
|
import unidecode
|
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
from haystack.query import SearchQuerySet
|
|
|
|
from haystack.inputs import Exact
|
|
|
|
|
|
|
|
searchable_models = [
|
|
|
|
Organization,
|
|
|
|
Network,
|
|
|
|
InternetExchange,
|
|
|
|
Facility,
|
|
|
|
]
|
|
|
|
|
2019-12-05 16:57:52 +00:00
|
|
|
|
2019-05-02 15:20:20 +00:00
|
|
|
def unaccent(v):
|
|
|
|
return unidecode.unidecode(v).lower()
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2019-12-05 16:57:52 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
def prepare_term(term):
|
|
|
|
try:
|
|
|
|
if len(term) == 1:
|
|
|
|
int(term)
|
|
|
|
term = f"AS{term}"
|
|
|
|
except ValueError:
|
|
|
|
pass
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
return unaccent(term)
|
2018-11-08 19:45:21 +00:00
|
|
|
|
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
def make_search_query(term):
|
|
|
|
if not term:
|
|
|
|
return SearchQuerySet().none()
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
term = prepare_term(term)
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
term_filters = Q(content=term) | Q(content__startswith=term)
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
return SearchQuerySet().filter(term_filters, status=Exact("ok"))
|
2018-11-08 19:45:21 +00:00
|
|
|
|
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
def make_name_search_query(term):
|
|
|
|
if not term:
|
|
|
|
return SearchQuerySet().none()
|
|
|
|
|
|
|
|
term = prepare_term(term)
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
term_filters = Q(name=term) | Q(name__startswith=term)
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
return SearchQuerySet().filter(term_filters, status=Exact("ok"))
|
2018-11-08 19:45:21 +00:00
|
|
|
|
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
def make_autocomplete_query(term):
|
|
|
|
if not term:
|
|
|
|
return SearchQuerySet().none()
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
term = prepare_term(term)
|
|
|
|
return SearchQuerySet().autocomplete(auto=term).filter(status=Exact("ok"))
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
|
|
|
|
def search(term, autocomplete=False):
|
2018-11-08 19:45:21 +00:00
|
|
|
"""
|
|
|
|
Search searchable objects (ixp, network, facility ...) by term
|
|
|
|
|
|
|
|
Returns result dict
|
|
|
|
"""
|
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
# t0 = time.time()
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
if autocomplete:
|
|
|
|
search_query = make_autocomplete_query(term)
|
|
|
|
limit = settings.SEARCH_RESULTS_AUTOCOMPLETE_LIMIT
|
2018-11-08 19:45:21 +00:00
|
|
|
else:
|
2021-07-07 17:57:04 -05:00
|
|
|
search_query = make_search_query(term)
|
|
|
|
limit = settings.SEARCH_RESULTS_LIMIT
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
search_tags = ("fac", "ix", "net", "org")
|
|
|
|
result = dict([(tag, []) for tag in search_tags])
|
|
|
|
|
|
|
|
for sq in search_query.models(*searchable_models)[:limit]:
|
|
|
|
model = sq.model
|
|
|
|
tag = model.HandleRef.tag
|
|
|
|
|
|
|
|
if tag == "org":
|
|
|
|
org_id = sq.pk
|
|
|
|
else:
|
|
|
|
org_id = sq.org_id
|
|
|
|
result[tag].append(
|
|
|
|
{
|
|
|
|
"id": sq.pk,
|
|
|
|
"name": sq.result_name,
|
|
|
|
"org_id": int(org_id),
|
|
|
|
"score": sq.score,
|
|
|
|
}
|
|
|
|
)
|
2018-11-08 19:45:21 +00:00
|
|
|
|
2020-01-08 13:29:58 -06:00
|
|
|
for k, items in list(result.items()):
|
2021-07-07 17:57:04 -05:00
|
|
|
# TODO: sort by score (wait until v2 search results)
|
2018-11-08 19:45:21 +00:00
|
|
|
result[k] = sorted(items, key=lambda row: row.get("name"))
|
|
|
|
|
2021-07-07 17:57:04 -05:00
|
|
|
# print("done", time.time() - t0)
|
|
|
|
|
2018-11-08 19:45:21 +00:00
|
|
|
return result
|