15
15
16
16
import logging
17
17
from collections import namedtuple
18
- from typing import Any , Dict , Optional
18
+ from typing import TYPE_CHECKING , Optional , Tuple
19
19
20
20
import msgpack
21
21
from unpaddedbase64 import decode_base64 , encode_base64
22
22
23
23
from synapse .api .constants import EventTypes , HistoryVisibility , JoinRules
24
24
from synapse .api .errors import Codes , HttpResponseException
25
- from synapse .types import ThirdPartyInstanceID
25
+ from synapse .types import JsonDict , ThirdPartyInstanceID
26
26
from synapse .util .caches .descriptors import cached
27
27
from synapse .util .caches .response_cache import ResponseCache
28
28
29
29
from ._base import BaseHandler
30
30
31
+ if TYPE_CHECKING :
32
+ from synapse .app .homeserver import HomeServer
33
+
31
34
logger = logging .getLogger (__name__ )
32
35
33
36
REMOTE_ROOM_LIST_POLL_INTERVAL = 60 * 1000
37
40
38
41
39
42
class RoomListHandler (BaseHandler ):
40
- def __init__ (self , hs ):
43
+ def __init__ (self , hs : "HomeServer" ):
41
44
super ().__init__ (hs )
42
45
self .enable_room_list_search = hs .config .enable_room_list_search
43
- self .response_cache = ResponseCache (hs , "room_list" )
46
+ self .response_cache = ResponseCache (
47
+ hs , "room_list"
48
+ ) # type: ResponseCache[Tuple[Optional[int], Optional[str], ThirdPartyInstanceID]]
44
49
self .remote_response_cache = ResponseCache (
45
50
hs , "remote_room_list" , timeout_ms = 30 * 1000
46
- )
51
+ ) # type: ResponseCache[Tuple[str, Optional[int], Optional[str], bool, Optional[str]]]
47
52
48
53
async def get_local_public_room_list (
49
54
self ,
50
- limit = None ,
51
- since_token = None ,
52
- search_filter = None ,
53
- network_tuple = EMPTY_THIRD_PARTY_ID ,
54
- from_federation = False ,
55
- ):
55
+ limit : Optional [ int ] = None ,
56
+ since_token : Optional [ str ] = None ,
57
+ search_filter : Optional [ dict ] = None ,
58
+ network_tuple : ThirdPartyInstanceID = EMPTY_THIRD_PARTY_ID ,
59
+ from_federation : bool = False ,
60
+ ) -> JsonDict :
56
61
"""Generate a local public room list.
57
62
58
63
There are multiple different lists: the main one plus one per third
59
64
party network. A client can ask for a specific list or to return all.
60
65
61
66
Args:
62
- limit (int|None)
63
- since_token (str|None)
64
- search_filter (dict|None)
65
- network_tuple (ThirdPartyInstanceID) : Which public list to use.
67
+ limit
68
+ since_token
69
+ search_filter
70
+ network_tuple: Which public list to use.
66
71
This can be (None, None) to indicate the main list, or a particular
67
72
appservice and network id to use an appservice specific one.
68
73
Setting to None returns all public rooms across all lists.
69
- from_federation (bool): true iff the request comes from the federation
70
- API
74
+ from_federation: true iff the request comes from the federation API
71
75
"""
72
76
if not self .enable_room_list_search :
73
77
return {"chunk" : [], "total_room_count_estimate" : 0 }
@@ -107,10 +111,10 @@ async def _get_public_room_list(
107
111
self ,
108
112
limit : Optional [int ] = None ,
109
113
since_token : Optional [str ] = None ,
110
- search_filter : Optional [Dict ] = None ,
114
+ search_filter : Optional [dict ] = None ,
111
115
network_tuple : ThirdPartyInstanceID = EMPTY_THIRD_PARTY_ID ,
112
116
from_federation : bool = False ,
113
- ) -> Dict [ str , Any ] :
117
+ ) -> JsonDict :
114
118
"""Generate a public room list.
115
119
Args:
116
120
limit: Maximum amount of rooms to return.
@@ -131,13 +135,17 @@ async def _get_public_room_list(
131
135
if since_token :
132
136
batch_token = RoomListNextBatch .from_token (since_token )
133
137
134
- bounds = (batch_token .last_joined_members , batch_token .last_room_id )
138
+ bounds = (
139
+ batch_token .last_joined_members ,
140
+ batch_token .last_room_id ,
141
+ ) # type: Optional[Tuple[int, str]]
135
142
forwards = batch_token .direction_is_forward
143
+ has_batch_token = True
136
144
else :
137
- batch_token = None
138
145
bounds = None
139
146
140
147
forwards = True
148
+ has_batch_token = False
141
149
142
150
# we request one more than wanted to see if there are more pages to come
143
151
probing_limit = limit + 1 if limit is not None else None
@@ -169,7 +177,7 @@ def build_room_entry(room):
169
177
170
178
results = [build_room_entry (r ) for r in results ]
171
179
172
- response = {}
180
+ response = {} # type: JsonDict
173
181
num_results = len (results )
174
182
if limit is not None :
175
183
more_to_come = num_results == probing_limit
@@ -187,7 +195,7 @@ def build_room_entry(room):
187
195
initial_entry = results [0 ]
188
196
189
197
if forwards :
190
- if batch_token :
198
+ if has_batch_token :
191
199
# If there was a token given then we assume that there
192
200
# must be previous results.
193
201
response ["prev_batch" ] = RoomListNextBatch (
@@ -203,7 +211,7 @@ def build_room_entry(room):
203
211
direction_is_forward = True ,
204
212
).to_token ()
205
213
else :
206
- if batch_token :
214
+ if has_batch_token :
207
215
response ["next_batch" ] = RoomListNextBatch (
208
216
last_joined_members = final_entry ["num_joined_members" ],
209
217
last_room_id = final_entry ["room_id" ],
@@ -293,7 +301,7 @@ async def generate_room_entry(
293
301
return None
294
302
295
303
# Return whether this room is open to federation users or not
296
- create_event = current_state . get (( EventTypes .Create , "" ))
304
+ create_event = current_state [ EventTypes .Create , "" ]
297
305
result ["m.federate" ] = create_event .content .get ("m.federate" , True )
298
306
299
307
name_event = current_state .get ((EventTypes .Name , "" ))
@@ -336,13 +344,13 @@ async def generate_room_entry(
336
344
337
345
async def get_remote_public_room_list (
338
346
self ,
339
- server_name ,
340
- limit = None ,
341
- since_token = None ,
342
- search_filter = None ,
343
- include_all_networks = False ,
344
- third_party_instance_id = None ,
345
- ):
347
+ server_name : str ,
348
+ limit : Optional [ int ] = None ,
349
+ since_token : Optional [ str ] = None ,
350
+ search_filter : Optional [ dict ] = None ,
351
+ include_all_networks : bool = False ,
352
+ third_party_instance_id : Optional [ str ] = None ,
353
+ ) -> JsonDict :
346
354
if not self .enable_room_list_search :
347
355
return {"chunk" : [], "total_room_count_estimate" : 0 }
348
356
@@ -399,13 +407,13 @@ async def get_remote_public_room_list(
399
407
400
408
async def _get_remote_list_cached (
401
409
self ,
402
- server_name ,
403
- limit = None ,
404
- since_token = None ,
405
- search_filter = None ,
406
- include_all_networks = False ,
407
- third_party_instance_id = None ,
408
- ):
410
+ server_name : str ,
411
+ limit : Optional [ int ] = None ,
412
+ since_token : Optional [ str ] = None ,
413
+ search_filter : Optional [ dict ] = None ,
414
+ include_all_networks : bool = False ,
415
+ third_party_instance_id : Optional [ str ] = None ,
416
+ ) -> JsonDict :
409
417
repl_layer = self .hs .get_federation_client ()
410
418
if search_filter :
411
419
# We can't cache when asking for search
@@ -456,24 +464,24 @@ class RoomListNextBatch(
456
464
REVERSE_KEY_DICT = {v : k for k , v in KEY_DICT .items ()}
457
465
458
466
@classmethod
459
- def from_token (cls , token ) :
467
+ def from_token (cls , token : str ) -> "RoomListNextBatch" :
460
468
decoded = msgpack .loads (decode_base64 (token ), raw = False )
461
469
return RoomListNextBatch (
462
470
** {cls .REVERSE_KEY_DICT [key ]: val for key , val in decoded .items ()}
463
471
)
464
472
465
- def to_token (self ):
473
+ def to_token (self ) -> str :
466
474
return encode_base64 (
467
475
msgpack .dumps (
468
476
{self .KEY_DICT [key ]: val for key , val in self ._asdict ().items ()}
469
477
)
470
478
)
471
479
472
- def copy_and_replace (self , ** kwds ):
480
+ def copy_and_replace (self , ** kwds ) -> "RoomListNextBatch" :
473
481
return self ._replace (** kwds )
474
482
475
483
476
- def _matches_room_entry (room_entry , search_filter ) :
484
+ def _matches_room_entry (room_entry : JsonDict , search_filter : dict ) -> bool :
477
485
if search_filter and search_filter .get ("generic_search_term" , None ):
478
486
generic_search_term = search_filter ["generic_search_term" ].upper ()
479
487
if generic_search_term in room_entry .get ("name" , "" ).upper ():
0 commit comments