Store room tag content and return the content in the m.tag event

This commit is contained in:
Mark Haines 2015-11-02 15:11:31 +00:00
parent 0e36756383
commit ddd8566f41
4 changed files with 41 additions and 22 deletions

View file

@ -405,7 +405,6 @@ class MessageHandler(BaseHandler):
tags = tags_by_room.get(event.room_id) tags = tags_by_room.get(event.room_id)
if tags: if tags:
private_user_data.append({ private_user_data.append({
"room_id": event.room_id,
"type": "m.tag", "type": "m.tag",
"content": {"tags": tags}, "content": {"tags": tags},
}) })
@ -466,7 +465,6 @@ class MessageHandler(BaseHandler):
private_user_data.append({ private_user_data.append({
"type": "m.tag", "type": "m.tag",
"content": {"tags": tags}, "content": {"tags": tags},
"room_id": room_id,
}) })
result["private_user_data"] = private_user_data result["private_user_data"] = private_user_data
@ -499,8 +497,8 @@ class MessageHandler(BaseHandler):
user_id, messages user_id, messages
) )
start_token = StreamToken(token[0], 0, 0, 0) start_token = StreamToken(token[0], 0, 0, 0, 0)
end_token = StreamToken(token[1], 0, 0, 0) end_token = StreamToken(token[1], 0, 0, 0, 0)
time_now = self.clock.time_msec() time_now = self.clock.time_msec()

View file

@ -16,12 +16,14 @@
from ._base import client_v2_pattern from ._base import client_v2_pattern
from synapse.http.servlet import RestServlet from synapse.http.servlet import RestServlet
from synapse.api.errors import AuthError from synapse.api.errors import AuthError, SynapseError
from twisted.internet import defer from twisted.internet import defer
import logging import logging
import simplejson as json
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -70,7 +72,13 @@ class TagServlet(RestServlet):
if user_id != auth_user.to_string(): if user_id != auth_user.to_string():
raise AuthError(403, "Cannot add tags for other users.") raise AuthError(403, "Cannot add tags for other users.")
max_id = yield self.store.add_tag_to_room(user_id, room_id, tag) try:
content_bytes = request.content.read()
body = json.loads(content_bytes)
except:
raise SynapseError(400, "Invalid tag JSON")
max_id = yield self.store.add_tag_to_room(user_id, room_id, tag, body)
yield self.notifier.on_new_event( yield self.notifier.on_new_event(
"private_user_data_key", max_id, users=[user_id] "private_user_data_key", max_id, users=[user_id]

View file

@ -18,6 +18,7 @@ CREATE TABLE IF NOT EXISTS room_tags(
user_id TEXT NOT NULL, user_id TEXT NOT NULL,
room_id TEXT NOT NULL, room_id TEXT NOT NULL,
tag TEXT NOT NULL, -- The name of the tag. tag TEXT NOT NULL, -- The name of the tag.
content TEXT NOT NULL, -- The JSON content of the tag.
CONSTRAINT room_tag_uniqueness UNIQUE (user_id, room_id, tag) CONSTRAINT room_tag_uniqueness UNIQUE (user_id, room_id, tag)
); );

View file

@ -18,6 +18,7 @@ from synapse.util.caches.descriptors import cached
from twisted.internet import defer from twisted.internet import defer
from .util.id_generators import StreamIdGenerator from .util.id_generators import StreamIdGenerator
import ujson as json
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -52,14 +53,15 @@ class TagsStore(SQLBaseStore):
""" """
deferred = self._simple_select_list( deferred = self._simple_select_list(
"room_tags", {"user_id": user_id}, ["room_id", "tag"] "room_tags", {"user_id": user_id}, ["room_id", "tag", "content"]
) )
@deferred.addCallback @deferred.addCallback
def tags_by_room(rows): def tags_by_room(rows):
tags_by_room = {} tags_by_room = {}
for row in rows: for row in rows:
tags_by_room.setdefault(row["room_id"], []).append(row["tag"]) room_tags = tags_by_room.setdefault(row["room_id"], {})
room_tags[row["tag"]] = json.loads(row["content"])
return tags_by_room return tags_by_room
return deferred return deferred
@ -105,31 +107,41 @@ class TagsStore(SQLBaseStore):
Returns: Returns:
A deferred list of string tags. A deferred list of string tags.
""" """
return self._simple_select_onecol( return self._simple_select_list(
table="room_tags", table="room_tags",
keyvalues={"user_id": user_id, "room_id": room_id}, keyvalues={"user_id": user_id, "room_id": room_id},
retcol="tag", retcols=("tag", "content"),
desc="get_tags_for_room", desc="get_tags_for_room",
) ).addCallback(lambda rows: {
row["tag"]: json.loads(row["content"]) for row in rows
})
@defer.inlineCallbacks @defer.inlineCallbacks
def add_tag_to_room(self, user_id, room_id, tag): def add_tag_to_room(self, user_id, room_id, tag, content):
"""Add a tag to a room for a user. """Add a tag to a room for a user.
Args:
user_id(str): The user to add a tag for.
room_id(str): The room to add a tag for.
tag(str): The tag name to add.
content(dict): A json object to associate with the tag.
Returns: Returns:
A deferred that completes once the tag has been added. A deferred that completes once the tag has been added.
""" """
content_json = json.dumps(content)
def add_tag_txn(txn, next_id): def add_tag_txn(txn, next_id):
sql = ( self._simple_upsert_txn(
"INSERT INTO room_tags (user_id, room_id, tag)" txn,
" VALUES (?, ?, ?)" table="room_tags",
keyvalues={
"user_id": user_id,
"room_id": room_id,
"tag": tag,
},
values={
"content": content_json,
}
) )
try:
txn.execute(sql, (user_id, room_id, tag))
except self.database_engine.module.IntegrityError:
# Return early if the row is already in the table
# and we don't need to bump the revision number of the
# private_user_data.
return
self._update_revision_txn(txn, user_id, room_id, next_id) self._update_revision_txn(txn, user_id, room_id, next_id)
with (yield self._private_user_data_id_gen.get_next(self)) as next_id: with (yield self._private_user_data_id_gen.get_next(self)) as next_id: