diff --git a/CHANGES.rst b/CHANGES.rst
index 414732ac28..aafd61ab4a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,3 +1,12 @@
+Changes in synapse v0.18.5 (2016-12-16)
+=======================================
+
+Bug fixes:
+
+* Fix federation /backfill returning events it shouldn't (PR #1700)
+* Fix crash in url preview (PR #1701)
+
+
Changes in synapse v0.18.5-rc3 (2016-12-13)
===========================================
diff --git a/README.rst b/README.rst
index 21bd63fd64..5ffcff22cd 100644
--- a/README.rst
+++ b/README.rst
@@ -120,6 +120,7 @@ Installing prerequisites on Mac OS X::
xcode-select --install
sudo easy_install pip
sudo pip install virtualenv
+ brew install pkg-config libffi
Installing prerequisites on Raspbian::
diff --git a/synapse/__init__.py b/synapse/__init__.py
index 825e90a2da..f006e10dc5 100644
--- a/synapse/__init__.py
+++ b/synapse/__init__.py
@@ -16,4 +16,4 @@
""" This is a reference implementation of a Matrix home server.
"""
-__version__ = "0.18.5-rc3"
+__version__ = "0.18.5"
diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index 771ab3bc43..1d07e4d02b 100644
--- a/synapse/handlers/federation.py
+++ b/synapse/handlers/federation.py
@@ -252,9 +252,12 @@ class FederationHandler(BaseHandler):
except:
return False
+ # Parses mapping `event_id -> (type, state_key) -> state event_id`
+ # to get all state ids that we're interested in.
event_map = yield self.store.get_events([
- e_id for key_to_eid in event_to_state_ids.values()
- for key, e_id in key_to_eid
+ e_id
+ for key_to_eid in event_to_state_ids.values()
+ for key, e_id in key_to_eid.items()
if key[0] != EventTypes.Member or check_match(key[1])
])
diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py
index b62773dcbe..c880f61685 100644
--- a/synapse/handlers/sync.py
+++ b/synapse/handlers/sync.py
@@ -576,16 +576,20 @@ class SyncHandler(object):
# We only delete messages when a new message comes in, but that's
# fine so long as we delete them at some point.
- logger.debug("Deleting messages up to %d", since_stream_id)
- yield self.store.delete_messages_for_device(
+ deleted = yield self.store.delete_messages_for_device(
user_id, device_id, since_stream_id
)
+ logger.info("Deleted %d to-device messages up to %d",
+ deleted, since_stream_id)
- logger.debug("Getting messages up to %d", now_token.to_device_key)
messages, stream_id = yield self.store.get_new_messages_for_device(
user_id, device_id, since_stream_id, now_token.to_device_key
)
- logger.debug("Got messages up to %d: %r", stream_id, messages)
+
+ logger.info(
+ "Returning %d to-device messages between %d and %d (current token: %d)",
+ len(messages), since_stream_id, stream_id, now_token.to_device_key
+ )
sync_result_builder.now_token = now_token.copy_and_replace(
"to_device_key", stream_id
)
diff --git a/synapse/rest/media/v1/preview_url_resource.py b/synapse/rest/media/v1/preview_url_resource.py
index 6a5a57102f..99760d622f 100644
--- a/synapse/rest/media/v1/preview_url_resource.py
+++ b/synapse/rest/media/v1/preview_url_resource.py
@@ -381,7 +381,10 @@ def _calc_og(tree, media_uri):
if 'og:title' not in og:
# do some basic spidering of the HTML
title = tree.xpath("(//title)[1] | (//h1)[1] | (//h2)[1] | (//h3)[1]")
- og['og:title'] = title[0].text.strip() if title else None
+ if title and title[0].text is not None:
+ og['og:title'] = title[0].text.strip()
+ else:
+ og['og:title'] = None
if 'og:image' not in og:
# TODO: extract a favicon failing all else
diff --git a/synapse/storage/deviceinbox.py b/synapse/storage/deviceinbox.py
index 87398d60bc..2821eb89c9 100644
--- a/synapse/storage/deviceinbox.py
+++ b/synapse/storage/deviceinbox.py
@@ -242,7 +242,7 @@ class DeviceInboxStore(SQLBaseStore):
device_id(str): The recipient device_id.
up_to_stream_id(int): Where to delete messages up to.
Returns:
- A deferred that resolves when the messages have been deleted.
+ A deferred that resolves to the number of messages deleted.
"""
def delete_messages_for_device_txn(txn):
sql = (
@@ -251,6 +251,7 @@ class DeviceInboxStore(SQLBaseStore):
" AND stream_id <= ?"
)
txn.execute(sql, (user_id, device_id, up_to_stream_id))
+ return txn.rowcount
return self.runInteraction(
"delete_messages_for_device", delete_messages_for_device_txn
diff --git a/tests/test_preview.py b/tests/test_preview.py
index ffa52e5dd4..5bd36c74aa 100644
--- a/tests/test_preview.py
+++ b/tests/test_preview.py
@@ -215,3 +215,53 @@ class PreviewUrlTestCase(unittest.TestCase):
u"og:title": u"Foo",
u"og:description": u"Some text."
})
+
+ def test_missing_title(self):
+ html = u"""
+ <html>
+ <body>
+ Some text.
+ </body>
+ </html>
+ """
+
+ og = decode_and_calc_og(html, "http://example.com/test.html")
+
+ self.assertEquals(og, {
+ u"og:title": None,
+ u"og:description": u"Some text."
+ })
+
+ def test_h1_as_title(self):
+ html = u"""
+ <html>
+ <meta property="og:description" content="Some text."/>
+ <body>
+ <h1>Title</h1>
+ </body>
+ </html>
+ """
+
+ og = decode_and_calc_og(html, "http://example.com/test.html")
+
+ self.assertEquals(og, {
+ u"og:title": u"Title",
+ u"og:description": u"Some text."
+ })
+
+ def test_missing_title_and_broken_h1(self):
+ html = u"""
+ <html>
+ <body>
+ <h1><a href="foo"/></h1>
+ Some text.
+ </body>
+ </html>
+ """
+
+ og = decode_and_calc_og(html, "http://example.com/test.html")
+
+ self.assertEquals(og, {
+ u"og:title": None,
+ u"og:description": u"Some text."
+ })
|