Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Add filters to search. #324

Merged
merged 12 commits into from
Oct 22, 2015
20 changes: 20 additions & 0 deletions synapse/api/filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,26 @@ def check(self, event):

return True

def filter_rooms(self, room_ids):
"""Apply the 'rooms' filter to a given list of rooms.

Args:
room_ids (list): A list of room_ids.

Returns:
list: A list of room_ids that match the filter
"""
room_ids = set(room_ids)

disallowed_rooms = set(self.filter_json.get("not_rooms", []))
room_ids -= disallowed_rooms

allowed_rooms = self.filter_json.get("rooms", None)
if allowed_rooms is not None:
room_ids &= set(allowed_rooms)

return room_ids

def filter(self, events):
return filter(self.check, events)

Expand Down
11 changes: 8 additions & 3 deletions synapse/handlers/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ._base import BaseHandler

from synapse.api.constants import Membership
from synapse.api.filtering import Filter
from synapse.api.errors import SynapseError
from synapse.events.utils import serialize_event

Expand Down Expand Up @@ -49,9 +50,12 @@ def search(self, user, content):
keys = content["search_categories"]["room_events"].get("keys", [
"content.body", "content.name", "content.topic",
])
filter_dict = content["search_categories"]["room_events"].get("filter", {})
except KeyError:
raise SynapseError(400, "Invalid search query")

filtr = Filter(filter_dict)

# TODO: Search through left rooms too
rooms = yield self.store.get_rooms_for_user_where_membership_is(
user.to_string(),
Expand All @@ -60,15 +64,16 @@ def search(self, user, content):
)
room_ids = set(r.room_id for r in rooms)

# TODO: Apply room filter to rooms list
room_ids = filtr.filter_rooms(room_ids)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that filtr is because filter is a builtin. I'd prefer something like search_filter rather than dropping vowels.


rank_map, event_map = yield self.store.search_msgs(room_ids, search_term, keys)

filtered_events = filtr.filter(event_map.values())

allowed_events = yield self._filter_events_for_client(
user.to_string(), event_map.values()
user.to_string(), filtered_events
)

# TODO: Filter allowed_events
# TODO: Add a limit

time_now = self.clock.time_msec()
Expand Down
2 changes: 1 addition & 1 deletion synapse/storage/prepare_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

# Remember to update this number every time a change is made to database
# schema files, so the users will be informed on server restarts.
SCHEMA_VERSION = 24
SCHEMA_VERSION = 25

dir_path = os.path.abspath(os.path.dirname(__file__))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@


POSTGRES_SQL = """
CREATE TABLE event_search (
CREATE TABLE IF NOT EXISTS event_search (
event_id TEXT,
room_id TEXT,
key TEXT,
Expand Down Expand Up @@ -53,7 +53,8 @@


SQLITE_TABLE = (
"CREATE VIRTUAL TABLE event_search USING fts3 ( event_id, room_id, key, value)"
"CREATE VIRTUAL TABLE IF NOT EXISTS event_search"
" USING fts3 ( event_id, room_id, key, value)"
)


Expand Down
10 changes: 6 additions & 4 deletions synapse/storage/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ def search_msgs(self, room_ids, search_term, keys):
clauses = []
args = []

clauses.append(
"room_id IN (%s)" % (",".join(["?"] * len(room_ids)),)
)
args.extend(room_ids)
# Make sure we don't explode because the person is in too many rooms.
if len(room_ids) > 500:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean the clauses are added if the user is in more than 500 rooms?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the clauses are omitted do we have a way to ensure that the user only sees the events for the rooms they are in?

clauses.append(
"room_id IN (%s)" % (",".join(["?"] * len(room_ids)),)
)
args.extend(room_ids)

local_clauses = []
for key in keys:
Expand Down