mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 07:02:26 +00:00
Add ability to make queries case sensitive
This commit is contained in:
parent
a5f0b2b72b
commit
8b9d1bc3b3
1 changed files with 62 additions and 39 deletions
101
search/engine.py
101
search/engine.py
|
@ -43,10 +43,11 @@ class Query:
|
||||||
"""Class representing a query.
|
"""Class representing a query.
|
||||||
It can contain the user-entered text, the operator for the query,
|
It can contain the user-entered text, the operator for the query,
|
||||||
and a list of subqueries"""
|
and a list of subqueries"""
|
||||||
def __init__(self, text=""):
|
def __init__(self, text="", case_sensitive=False):
|
||||||
self.text = text # Content of the query
|
self.text = text # Content of the query
|
||||||
self.operator = None # Whether a special char (ex "+") was used
|
self.operator = None # Whether a special char (ex "+") was used
|
||||||
self.subqueries = None # When splitting the query in subparts
|
self.subqueries = None # When splitting the query in subparts
|
||||||
|
self.case_sensitive = case_sensitive
|
||||||
|
|
||||||
def add_char(self, char):
|
def add_char(self, char):
|
||||||
"""Add the given char to the query's text"""
|
"""Add the given char to the query's text"""
|
||||||
|
@ -61,8 +62,9 @@ class Query:
|
||||||
if self.subqueries is None:
|
if self.subqueries is None:
|
||||||
self.subqueries = []
|
self.subqueries = []
|
||||||
|
|
||||||
self.subqueries.append(Query(self.text))
|
self.subqueries.append(Query(self.text, self.case_sensitive))
|
||||||
self.text = ""
|
self.text = ""
|
||||||
|
self.case_sensitive = False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def plaintext(self):
|
def plaintext(self):
|
||||||
|
@ -70,6 +72,9 @@ class Query:
|
||||||
if self.operator is not None:
|
if self.operator is not None:
|
||||||
return self.operator.join([q.plaintext for q in self.subqueries])
|
return self.operator.join([q.plaintext for q in self.subqueries])
|
||||||
|
|
||||||
|
if self.case_sensitive:
|
||||||
|
return "\"{}\"".format(self.text)
|
||||||
|
|
||||||
return self.text
|
return self.text
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,7 +148,18 @@ def finish_results(request, results, col, order):
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
def search_single_word(word, filters, user, start, end, user_state, aff):
|
def contains_filter(attribute, word, case_sensitive=False):
|
||||||
|
"""Create a django model filtering whether the given attribute
|
||||||
|
contains the specified value."""
|
||||||
|
if case_sensitive:
|
||||||
|
attr = "{}__{}".format(attribute, "contains")
|
||||||
|
else:
|
||||||
|
attr = "{}__{}".format(attribute, "icontains")
|
||||||
|
|
||||||
|
return Q(**{attr: word})
|
||||||
|
|
||||||
|
|
||||||
|
def search_single_word(word, filters, user, start, end, user_state, aff, case_sensitive=False):
|
||||||
""" Construct the correct filters to match differents fields of some models
|
""" Construct the correct filters to match differents fields of some models
|
||||||
with the given query according to the given filters.
|
with the given query according to the given filters.
|
||||||
The match field are either CharField or IntegerField that will be displayed
|
The match field are either CharField or IntegerField that will be displayed
|
||||||
|
@ -154,15 +170,14 @@ def search_single_word(word, filters, user, start, end, user_state, aff):
|
||||||
# Users
|
# Users
|
||||||
if "0" in aff:
|
if "0" in aff:
|
||||||
filter_clubs = (
|
filter_clubs = (
|
||||||
Q(surname__icontains=word)
|
contains_filter("surname", word, case_sensitive)
|
||||||
| Q(pseudo__icontains=word)
|
| contains_filter("pseudo", word, case_sensitive)
|
||||||
| Q(room__name__icontains=word)
|
| contains_filter("email", word, case_sensitive)
|
||||||
| Q(email__icontains=word)
|
| contains_filter("telephone", word, case_sensitive)
|
||||||
| Q(telephone__icontains=word)
|
| contains_filter("room__name", word, case_sensitive)
|
||||||
| Q(room__name__icontains=word)
|
| contains_filter("room__building__name", word, case_sensitive)
|
||||||
| Q(room__building__name__icontains=word)
|
|
||||||
)
|
)
|
||||||
filter_users = (filter_clubs | Q(name__icontains=word))
|
filter_users = (filter_clubs | contains_filter("name", word, case_sensitive))
|
||||||
|
|
||||||
if not User.can_view_all(user)[0]:
|
if not User.can_view_all(user)[0]:
|
||||||
filter_clubs &= Q(id=user.id)
|
filter_clubs &= Q(id=user.id)
|
||||||
|
@ -177,12 +192,12 @@ def search_single_word(word, filters, user, start, end, user_state, aff):
|
||||||
# Machines
|
# Machines
|
||||||
if "1" in aff:
|
if "1" in aff:
|
||||||
filter_machines = (
|
filter_machines = (
|
||||||
Q(name__icontains=word)
|
contains_filter("name", word, case_sensitive)
|
||||||
| (Q(user__pseudo__icontains=word) & Q(user__state__in=user_state))
|
| contains_filter("user__pseudo", word, case_sensitive) & Q(user__state__in=user_state)
|
||||||
| Q(interface__domain__name__icontains=word)
|
| contains_filter("interface__domain__name", word, case_sensitive)
|
||||||
| Q(interface__domain__related_domain__name__icontains=word)
|
| contains_filter("interface__domain__related_domain__name", word, case_sensitive)
|
||||||
| Q(interface__mac_address__icontains=word)
|
| contains_filter("interface__mac_address", word, case_sensitive)
|
||||||
| Q(interface__ipv4__ipv4__icontains=word)
|
| contains_filter("interface__ipv4__ipv4", word, case_sensitive)
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
_mac_addr = EUI(word, 48)
|
_mac_addr = EUI(word, 48)
|
||||||
|
@ -195,9 +210,8 @@ def search_single_word(word, filters, user, start, end, user_state, aff):
|
||||||
|
|
||||||
# Factures
|
# Factures
|
||||||
if "2" in aff:
|
if "2" in aff:
|
||||||
filter_factures = Q(user__pseudo__icontains=word) & Q(
|
filter_factures = contains_filter("user__pseudo", word, case_sensitive)
|
||||||
user__state__in=user_state
|
& Q(user__state__in=user_state)
|
||||||
)
|
|
||||||
if start is not None:
|
if start is not None:
|
||||||
filter_factures &= Q(date__gte=start)
|
filter_factures &= Q(date__gte=start)
|
||||||
if end is not None:
|
if end is not None:
|
||||||
|
@ -207,8 +221,9 @@ def search_single_word(word, filters, user, start, end, user_state, aff):
|
||||||
# Bans
|
# Bans
|
||||||
if "3" in aff:
|
if "3" in aff:
|
||||||
filter_bans = (
|
filter_bans = (
|
||||||
Q(user__pseudo__icontains=word) & Q(user__state__in=user_state)
|
contains_filter("user__pseudo", word, case_sensitive)
|
||||||
) | Q(raison__icontains=word)
|
& Q(user__state__in=user_state)
|
||||||
|
) | contains_filter("raison", word, case_sensitive)
|
||||||
if start is not None:
|
if start is not None:
|
||||||
filter_bans &= (
|
filter_bans &= (
|
||||||
(Q(date_start__gte=start) & Q(date_end__gte=start))
|
(Q(date_start__gte=start) & Q(date_end__gte=start))
|
||||||
|
@ -226,8 +241,9 @@ def search_single_word(word, filters, user, start, end, user_state, aff):
|
||||||
# Whitelists
|
# Whitelists
|
||||||
if "4" in aff:
|
if "4" in aff:
|
||||||
filter_whitelists = (
|
filter_whitelists = (
|
||||||
Q(user__pseudo__icontains=word) & Q(user__state__in=user_state)
|
contains_filter("user__pseudo", word, case_sensitive)
|
||||||
) | Q(raison__icontains=word)
|
& Q(user__state__in=user_state)
|
||||||
|
) | contains_filter("raison", word, case_sensitive)
|
||||||
if start is not None:
|
if start is not None:
|
||||||
filter_whitelists &= (
|
filter_whitelists &= (
|
||||||
(Q(date_start__gte=start) & Q(date_end__gte=start))
|
(Q(date_start__gte=start) & Q(date_end__gte=start))
|
||||||
|
@ -245,7 +261,10 @@ def search_single_word(word, filters, user, start, end, user_state, aff):
|
||||||
# Rooms
|
# Rooms
|
||||||
if "5" in aff and Room.can_view_all(user):
|
if "5" in aff and Room.can_view_all(user):
|
||||||
filter_rooms = (
|
filter_rooms = (
|
||||||
Q(details__icontains=word) | Q(name__icontains=word) | Q(port__details=word) | Q(building__name__icontains=word)
|
contains_filter("details", word, case_sensitive)
|
||||||
|
| contains_filter("name", word, case_sensitive)
|
||||||
|
| contains_filter("building__name", word, case_sensitive)
|
||||||
|
| Q(port__details=word)
|
||||||
)
|
)
|
||||||
|
|
||||||
filters["rooms"] |= filter_rooms
|
filters["rooms"] |= filter_rooms
|
||||||
|
@ -253,12 +272,12 @@ def search_single_word(word, filters, user, start, end, user_state, aff):
|
||||||
# Switch ports
|
# Switch ports
|
||||||
if "6" in aff and User.can_view_all(user):
|
if "6" in aff and User.can_view_all(user):
|
||||||
filter_ports = (
|
filter_ports = (
|
||||||
Q(room__name__icontains=word)
|
contains_filter("room__name", word, case_sensitive)
|
||||||
| Q(machine_interface__domain__name__icontains=word)
|
| contains_filter("machine_interface__domain__name", word, case_sensitive)
|
||||||
| Q(related__switch__interface__domain__name__icontains=word)
|
| contains_filter("related__switch__interface__domain__name", word, case_sensitive)
|
||||||
| Q(custom_profile__name__icontains=word)
|
| contains_filter("custom_profile__name", word, case_sensitive)
|
||||||
| Q(custom_profile__profil_default__icontains=word)
|
| contains_filter("custom_profile__profil_default", word, case_sensitive)
|
||||||
| Q(details__icontains=word)
|
| contains_filter("details", word, case_sensitive)
|
||||||
)
|
)
|
||||||
if is_int(word):
|
if is_int(word):
|
||||||
filter_ports |= Q(port=word)
|
filter_ports |= Q(port=word)
|
||||||
|
@ -267,13 +286,13 @@ def search_single_word(word, filters, user, start, end, user_state, aff):
|
||||||
# Switches
|
# Switches
|
||||||
if "7" in aff and Switch.can_view_all(user):
|
if "7" in aff and Switch.can_view_all(user):
|
||||||
filter_switches = (
|
filter_switches = (
|
||||||
Q(interface__domain__name__icontains=word)
|
contains_filter("interface__domain__name", word, case_sensitive)
|
||||||
| Q(interface__ipv4__ipv4__icontains=word)
|
| contains_filter("interface__ipv4__ipv4", word, case_sensitive)
|
||||||
| Q(switchbay__building__name__icontains=word)
|
| contains_filter("switchbay__building__name", word, case_sensitive)
|
||||||
| Q(stack__name__icontains=word)
|
| contains_filter("stack__name", word, case_sensitive)
|
||||||
| Q(model__reference__icontains=word)
|
| contains_filter("model__reference", word, case_sensitive)
|
||||||
| Q(model__constructor__name__icontains=word)
|
| contains_filter("model__constructor__name", word, case_sensitive)
|
||||||
| Q(interface__details__icontains=word)
|
| contains_filter("interface__details", word, case_sensitive)
|
||||||
)
|
)
|
||||||
if is_int(word):
|
if is_int(word):
|
||||||
filter_switches |= Q(number=word) | Q(stack_member_id=word)
|
filter_switches |= Q(number=word) | Q(stack_member_id=word)
|
||||||
|
@ -357,7 +376,7 @@ def search_single_query(query, filters, user, start, end, user_state, aff):
|
||||||
return filters
|
return filters
|
||||||
|
|
||||||
# Handle standard queries
|
# Handle standard queries
|
||||||
return search_single_word(query.text, filters, user, start, end, user_state, aff)
|
return search_single_word(query.text, filters, user, start, end, user_state, aff, q.case_sensitive)
|
||||||
|
|
||||||
|
|
||||||
def create_queries(query):
|
def create_queries(query):
|
||||||
|
@ -400,6 +419,10 @@ def create_queries(query):
|
||||||
if char == '"':
|
if char == '"':
|
||||||
# Toogle the keep_intact state, if true, we are between two "
|
# Toogle the keep_intact state, if true, we are between two "
|
||||||
keep_intact = not keep_intact
|
keep_intact = not keep_intact
|
||||||
|
|
||||||
|
if keep_intact:
|
||||||
|
current_query.case_sensitive = True
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if keep_intact:
|
if keep_intact:
|
||||||
|
|
Loading…
Reference in a new issue