mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2024-10-01 11:49:51 -04:00
Implement filtering
This commit is contained in:
parent
fa0dcbc8fa
commit
acd16ad86a
@ -20,6 +20,7 @@ from jsonschema import FormatChecker
|
|||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
|
from synapse.api.constants import LabelsField
|
||||||
from synapse.api.errors import SynapseError
|
from synapse.api.errors import SynapseError
|
||||||
from synapse.storage.presence import UserPresenceState
|
from synapse.storage.presence import UserPresenceState
|
||||||
from synapse.types import RoomID, UserID
|
from synapse.types import RoomID, UserID
|
||||||
@ -66,6 +67,8 @@ ROOM_EVENT_FILTER_SCHEMA = {
|
|||||||
"contains_url": {"type": "boolean"},
|
"contains_url": {"type": "boolean"},
|
||||||
"lazy_load_members": {"type": "boolean"},
|
"lazy_load_members": {"type": "boolean"},
|
||||||
"include_redundant_members": {"type": "boolean"},
|
"include_redundant_members": {"type": "boolean"},
|
||||||
|
"org.matrix.labels": {"type": "array", "items": {"type": "string"}},
|
||||||
|
"org.matrix.not_labels": {"type": "array", "items": {"type": "string"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,6 +262,9 @@ class Filter(object):
|
|||||||
|
|
||||||
self.contains_url = self.filter_json.get("contains_url", None)
|
self.contains_url = self.filter_json.get("contains_url", None)
|
||||||
|
|
||||||
|
self.labels = self.filter_json.get("org.matrix.labels", None)
|
||||||
|
self.not_labels = self.filter_json.get("org.matrix.not_labels", [])
|
||||||
|
|
||||||
def filters_all_types(self):
|
def filters_all_types(self):
|
||||||
return "*" in self.not_types
|
return "*" in self.not_types
|
||||||
|
|
||||||
@ -282,6 +288,7 @@ class Filter(object):
|
|||||||
room_id = None
|
room_id = None
|
||||||
ev_type = "m.presence"
|
ev_type = "m.presence"
|
||||||
contains_url = False
|
contains_url = False
|
||||||
|
labels = []
|
||||||
else:
|
else:
|
||||||
sender = event.get("sender", None)
|
sender = event.get("sender", None)
|
||||||
if not sender:
|
if not sender:
|
||||||
@ -300,10 +307,11 @@ class Filter(object):
|
|||||||
content = event.get("content", {})
|
content = event.get("content", {})
|
||||||
# check if there is a string url field in the content for filtering purposes
|
# check if there is a string url field in the content for filtering purposes
|
||||||
contains_url = isinstance(content.get("url"), text_type)
|
contains_url = isinstance(content.get("url"), text_type)
|
||||||
|
labels = content.get(LabelsField)
|
||||||
|
|
||||||
return self.check_fields(room_id, sender, ev_type, contains_url)
|
return self.check_fields(room_id, sender, ev_type, labels, contains_url)
|
||||||
|
|
||||||
def check_fields(self, room_id, sender, event_type, contains_url):
|
def check_fields(self, room_id, sender, event_type, labels, contains_url):
|
||||||
"""Checks whether the filter matches the given event fields.
|
"""Checks whether the filter matches the given event fields.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -313,6 +321,7 @@ class Filter(object):
|
|||||||
"rooms": lambda v: room_id == v,
|
"rooms": lambda v: room_id == v,
|
||||||
"senders": lambda v: sender == v,
|
"senders": lambda v: sender == v,
|
||||||
"types": lambda v: _matches_wildcard(event_type, v),
|
"types": lambda v: _matches_wildcard(event_type, v),
|
||||||
|
"labels": lambda v: v in labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, match_func in literal_keys.items():
|
for name, match_func in literal_keys.items():
|
||||||
|
@ -229,6 +229,14 @@ def filter_to_clause(event_filter):
|
|||||||
clauses.append("contains_url = ?")
|
clauses.append("contains_url = ?")
|
||||||
args.append(event_filter.contains_url)
|
args.append(event_filter.contains_url)
|
||||||
|
|
||||||
|
# We're only applying the "labels" filter on the database query, because applying the
|
||||||
|
# "not_labels" filter via a SQL query is non-trivial. Instead, we let
|
||||||
|
# event_filter.check_fields apply it, which is not as efficient but makes the
|
||||||
|
# implementation simpler.
|
||||||
|
if event_filter.labels:
|
||||||
|
clauses.append("(%s)" % " OR ".join("label = ?" for _ in event_filter.labels))
|
||||||
|
args.extend(event_filter.labels)
|
||||||
|
|
||||||
return " AND ".join(clauses), args
|
return " AND ".join(clauses), args
|
||||||
|
|
||||||
|
|
||||||
@ -866,6 +874,7 @@ class StreamWorkerStore(EventsWorkerStore, SQLBaseStore):
|
|||||||
sql = (
|
sql = (
|
||||||
"SELECT event_id, topological_ordering, stream_ordering"
|
"SELECT event_id, topological_ordering, stream_ordering"
|
||||||
" FROM events"
|
" FROM events"
|
||||||
|
" LEFT JOIN event_labels USING (event_id)"
|
||||||
" WHERE outlier = ? AND room_id = ? AND %(bounds)s"
|
" WHERE outlier = ? AND room_id = ? AND %(bounds)s"
|
||||||
" ORDER BY topological_ordering %(order)s,"
|
" ORDER BY topological_ordering %(order)s,"
|
||||||
" stream_ordering %(order)s LIMIT ?"
|
" stream_ordering %(order)s LIMIT ?"
|
||||||
|
Loading…
Reference in New Issue
Block a user