Merge pull request #394 from matrix-org/erikj/search

Add options for including state in search results
pull/395/head
Erik Johnston 2015-11-20 16:31:24 +00:00
commit 93f7bb8dd5
1 changed files with 54 additions and 1 deletions

View File

@ -17,13 +17,14 @@ from twisted.internet import defer
from ._base import BaseHandler from ._base import BaseHandler
from synapse.api.constants import Membership from synapse.api.constants import Membership, EventTypes
from synapse.api.filtering import Filter from synapse.api.filtering import Filter
from synapse.api.errors import SynapseError from synapse.api.errors import SynapseError
from synapse.events.utils import serialize_event from synapse.events.utils import serialize_event
from unpaddedbase64 import decode_base64, encode_base64 from unpaddedbase64 import decode_base64, encode_base64
import itertools
import logging import logging
@ -79,6 +80,9 @@ class SearchHandler(BaseHandler):
# What to order results by (impacts whether pagination can be doen) # What to order results by (impacts whether pagination can be doen)
order_by = room_cat.get("order_by", "rank") order_by = room_cat.get("order_by", "rank")
# Return the current state of the rooms?
include_state = room_cat.get("include_state", False)
# Include context around each event? # Include context around each event?
event_context = room_cat.get( event_context = room_cat.get(
"event_context", None "event_context", None
@ -96,6 +100,10 @@ class SearchHandler(BaseHandler):
after_limit = int(event_context.get( after_limit = int(event_context.get(
"after_limit", 5 "after_limit", 5
)) ))
# Return the historic display name and avatar for the senders
# of the events?
include_profile = bool(event_context.get("include_profile", False))
except KeyError: except KeyError:
raise SynapseError(400, "Invalid search query") raise SynapseError(400, "Invalid search query")
@ -269,6 +277,33 @@ class SearchHandler(BaseHandler):
"room_key", res["end"] "room_key", res["end"]
).to_string() ).to_string()
if include_profile:
senders = set(
ev.sender
for ev in itertools.chain(
res["events_before"], [event], res["events_after"]
)
)
if res["events_after"]:
last_event_id = res["events_after"][-1].event_id
else:
last_event_id = event.event_id
state = yield self.store.get_state_for_event(
last_event_id,
types=[(EventTypes.Member, sender) for sender in senders]
)
res["profile_info"] = {
s.state_key: {
"displayname": s.content.get("displayname", None),
"avatar_url": s.content.get("avatar_url", None),
}
for s in state.values()
if s.type == EventTypes.Member and s.state_key in senders
}
contexts[event.event_id] = res contexts[event.event_id] = res
else: else:
contexts = {} contexts = {}
@ -287,6 +322,18 @@ class SearchHandler(BaseHandler):
for e in context["events_after"] for e in context["events_after"]
] ]
state_results = {}
if include_state:
rooms = set(e.room_id for e in allowed_events)
for room_id in rooms:
state = yield self.state_handler.get_current_state(room_id)
state_results[room_id] = state.values()
state_results.values()
# We're now about to serialize the events. We should not make any
# blocking calls after this. Otherwise the 'age' will be wrong
results = { results = {
e.event_id: { e.event_id: {
"rank": rank_map[e.event_id], "rank": rank_map[e.event_id],
@ -303,6 +350,12 @@ class SearchHandler(BaseHandler):
"count": len(results) "count": len(results)
} }
if state_results:
rooms_cat_res["state"] = {
room_id: [serialize_event(e, time_now) for e in state]
for room_id, state in state_results.items()
}
if room_groups and "room_id" in group_keys: if room_groups and "room_id" in group_keys:
rooms_cat_res.setdefault("groups", {})["room_id"] = room_groups rooms_cat_res.setdefault("groups", {})["room_id"] = room_groups