1919import urllib .parse
2020from email .mime .multipart import MIMEMultipart
2121from email .mime .text import MIMEText
22- from typing import Iterable , List , TypeVar
22+ from typing import TYPE_CHECKING , Any , Dict , Iterable , List , Optional , TypeVar
2323
2424import bleach
2525import jinja2
2626
2727from synapse .api .constants import EventTypes , Membership
2828from synapse .api .errors import StoreError
2929from synapse .config .emailconfig import EmailSubjectConfig
30+ from synapse .events import EventBase
3031from synapse .logging .context import make_deferred_yieldable
3132from synapse .push .presentable_names import (
3233 calculate_room_name ,
3334 descriptor_from_member_events ,
3435 name_from_member_event ,
3536)
36- from synapse .types import UserID
37+ from synapse .types import StateMap , UserID
3738from synapse .util .async_helpers import concurrently_execute
3839from synapse .visibility import filter_events_for_client
3940
41+ if TYPE_CHECKING :
42+ from synapse .app .homeserver import HomeServer
43+
4044logger = logging .getLogger (__name__ )
4145
4246T = TypeVar ("T" )
9397
9498
9599class Mailer :
96- def __init__ (self , hs , app_name , template_html , template_text ):
100+ def __init__ (
101+ self ,
102+ hs : "HomeServer" ,
103+ app_name : str ,
104+ template_html : jinja2 .Template ,
105+ template_text : jinja2 .Template ,
106+ ):
97107 self .hs = hs
98108 self .template_html = template_html
99109 self .template_text = template_text
@@ -108,17 +118,19 @@ def __init__(self, hs, app_name, template_html, template_text):
108118
109119 logger .info ("Created Mailer for app_name %s" % app_name )
110120
111- async def send_password_reset_mail (self , email_address , token , client_secret , sid ):
121+ async def send_password_reset_mail (
122+ self , email_address : str , token : str , client_secret : str , sid : str
123+ ) -> None :
112124 """Send an email with a password reset link to a user
113125
114126 Args:
115- email_address (str) : Email address we're sending the password
127+ email_address: Email address we're sending the password
116128 reset to
117- token (str) : Unique token generated by the server to verify
129+ token: Unique token generated by the server to verify
118130 the email was received
119- client_secret (str) : Unique token generated by the client to
131+ client_secret: Unique token generated by the client to
120132 group together multiple email sending attempts
121- sid (str) : The generated session ID
133+ sid: The generated session ID
122134 """
123135 params = {"token" : token , "client_secret" : client_secret , "sid" : sid }
124136 link = (
@@ -136,17 +148,19 @@ async def send_password_reset_mail(self, email_address, token, client_secret, si
136148 template_vars ,
137149 )
138150
139- async def send_registration_mail (self , email_address , token , client_secret , sid ):
151+ async def send_registration_mail (
152+ self , email_address : str , token : str , client_secret : str , sid : str
153+ ) -> None :
140154 """Send an email with a registration confirmation link to a user
141155
142156 Args:
143- email_address (str) : Email address we're sending the registration
157+ email_address: Email address we're sending the registration
144158 link to
145- token (str) : Unique token generated by the server to verify
159+ token: Unique token generated by the server to verify
146160 the email was received
147- client_secret (str) : Unique token generated by the client to
161+ client_secret: Unique token generated by the client to
148162 group together multiple email sending attempts
149- sid (str) : The generated session ID
163+ sid: The generated session ID
150164 """
151165 params = {"token" : token , "client_secret" : client_secret , "sid" : sid }
152166 link = (
@@ -164,18 +178,20 @@ async def send_registration_mail(self, email_address, token, client_secret, sid)
164178 template_vars ,
165179 )
166180
167- async def send_add_threepid_mail (self , email_address , token , client_secret , sid ):
181+ async def send_add_threepid_mail (
182+ self , email_address : str , token : str , client_secret : str , sid : str
183+ ) -> None :
168184 """Send an email with a validation link to a user for adding a 3pid to their account
169185
170186 Args:
171- email_address (str) : Email address we're sending the validation link to
187+ email_address: Email address we're sending the validation link to
172188
173- token (str) : Unique token generated by the server to verify the email was received
189+ token: Unique token generated by the server to verify the email was received
174190
175- client_secret (str) : Unique token generated by the client to group together
191+ client_secret: Unique token generated by the client to group together
176192 multiple email sending attempts
177193
178- sid (str) : The generated session ID
194+ sid: The generated session ID
179195 """
180196 params = {"token" : token , "client_secret" : client_secret , "sid" : sid }
181197 link = (
@@ -194,16 +210,21 @@ async def send_add_threepid_mail(self, email_address, token, client_secret, sid)
194210 )
195211
196212 async def send_notification_mail (
197- self , app_id , user_id , email_address , push_actions , reason
198- ):
213+ self ,
214+ app_id : str ,
215+ user_id : str ,
216+ email_address : str ,
217+ push_actions : Iterable [Dict [str , Any ]],
218+ reason : Dict [str , Any ],
219+ ) -> None :
199220 """Send email regarding a user's room notifications"""
200221 rooms_in_order = deduped_ordered_list ([pa ["room_id" ] for pa in push_actions ])
201222
202223 notif_events = await self .store .get_events (
203224 [pa ["event_id" ] for pa in push_actions ]
204225 )
205226
206- notifs_by_room = {}
227+ notifs_by_room = {} # type: Dict[str, List[Dict[str, Any]]]
207228 for pa in push_actions :
208229 notifs_by_room .setdefault (pa ["room_id" ], []).append (pa )
209230
@@ -262,7 +283,9 @@ async def _fetch_room_state(room_id):
262283
263284 await self .send_email (email_address , summary_text , template_vars )
264285
265- async def send_email (self , email_address , subject , extra_template_vars ):
286+ async def send_email (
287+ self , email_address : str , subject : str , extra_template_vars : Dict [str , Any ]
288+ ) -> None :
266289 """Send an email with the given information and template text"""
267290 try :
268291 from_string = self .hs .config .email_notif_from % {"app" : self .app_name }
@@ -315,8 +338,13 @@ async def send_email(self, email_address, subject, extra_template_vars):
315338 )
316339
317340 async def get_room_vars (
318- self , room_id , user_id , notifs , notif_events , room_state_ids
319- ):
341+ self ,
342+ room_id : str ,
343+ user_id : str ,
344+ notifs : Iterable [Dict [str , Any ]],
345+ notif_events : Dict [str , EventBase ],
346+ room_state_ids : StateMap [str ],
347+ ) -> Dict [str , Any ]:
320348 # Check if one of the notifs is an invite event for the user.
321349 is_invite = False
322350 for n in notifs :
@@ -334,7 +362,7 @@ async def get_room_vars(
334362 "notifs" : [],
335363 "invite" : is_invite ,
336364 "link" : self .make_room_link (room_id ),
337- }
365+ } # type: Dict[str, Any]
338366
339367 if not is_invite :
340368 for n in notifs :
@@ -365,7 +393,13 @@ async def get_room_vars(
365393
366394 return room_vars
367395
368- async def get_notif_vars (self , notif , user_id , notif_event , room_state_ids ):
396+ async def get_notif_vars (
397+ self ,
398+ notif : Dict [str , Any ],
399+ user_id : str ,
400+ notif_event : EventBase ,
401+ room_state_ids : StateMap [str ],
402+ ) -> Dict [str , Any ]:
369403 results = await self .store .get_events_around (
370404 notif ["room_id" ],
371405 notif ["event_id" ],
@@ -391,7 +425,9 @@ async def get_notif_vars(self, notif, user_id, notif_event, room_state_ids):
391425
392426 return ret
393427
394- async def get_message_vars (self , notif , event , room_state_ids ):
428+ async def get_message_vars (
429+ self , notif : Dict [str , Any ], event : EventBase , room_state_ids : StateMap [str ]
430+ ) -> Optional [Dict [str , Any ]]:
395431 if event .type != EventTypes .Message and event .type != EventTypes .Encrypted :
396432 return None
397433
@@ -432,7 +468,9 @@ async def get_message_vars(self, notif, event, room_state_ids):
432468
433469 return ret
434470
435- def add_text_message_vars (self , messagevars , event ):
471+ def add_text_message_vars (
472+ self , messagevars : Dict [str , Any ], event : EventBase
473+ ) -> None :
436474 msgformat = event .content .get ("format" )
437475
438476 messagevars ["format" ] = msgformat
@@ -445,15 +483,18 @@ def add_text_message_vars(self, messagevars, event):
445483 elif body :
446484 messagevars ["body_text_html" ] = safe_text (body )
447485
448- return messagevars
449-
450- def add_image_message_vars ( self , messagevars , event ) :
486+ def add_image_message_vars (
487+ self , messagevars : Dict [ str , Any ], event : EventBase
488+ ) -> None :
451489 messagevars ["image_url" ] = event .content ["url" ]
452490
453- return messagevars
454-
455491 async def make_summary_text (
456- self , notifs_by_room , room_state_ids , notif_events , user_id , reason
492+ self ,
493+ notifs_by_room : Dict [str , List [Dict [str , Any ]]],
494+ room_state_ids : Dict [str , StateMap [str ]],
495+ notif_events : Dict [str , EventBase ],
496+ user_id : str ,
497+ reason : Dict [str , Any ],
457498 ):
458499 if len (notifs_by_room ) == 1 :
459500 # Only one room has new stuff
@@ -580,7 +621,7 @@ async def make_summary_text(
580621 "app" : self .app_name ,
581622 }
582623
583- def make_room_link (self , room_id ) :
624+ def make_room_link (self , room_id : str ) -> str :
584625 if self .hs .config .email_riot_base_url :
585626 base_url = "%s/#/room" % (self .hs .config .email_riot_base_url )
586627 elif self .app_name == "Vector" :
@@ -590,7 +631,7 @@ def make_room_link(self, room_id):
590631 base_url = "https://matrix.to/#"
591632 return "%s/%s" % (base_url , room_id )
592633
593- def make_notif_link (self , notif ) :
634+ def make_notif_link (self , notif : Dict [ str , str ]) -> str :
594635 if self .hs .config .email_riot_base_url :
595636 return "%s/#/room/%s/%s" % (
596637 self .hs .config .email_riot_base_url ,
@@ -606,7 +647,9 @@ def make_notif_link(self, notif):
606647 else :
607648 return "https://matrix.to/#/%s/%s" % (notif ["room_id" ], notif ["event_id" ])
608649
609- def make_unsubscribe_link (self , user_id , app_id , email_address ):
650+ def make_unsubscribe_link (
651+ self , user_id : str , app_id : str , email_address : str
652+ ) -> str :
610653 params = {
611654 "access_token" : self .macaroon_gen .generate_delete_pusher_token (user_id ),
612655 "app_id" : app_id ,
@@ -620,7 +663,7 @@ def make_unsubscribe_link(self, user_id, app_id, email_address):
620663 )
621664
622665
623- def safe_markup (raw_html ) :
666+ def safe_markup (raw_html : str ) -> jinja2 . Markup :
624667 return jinja2 .Markup (
625668 bleach .linkify (
626669 bleach .clean (
@@ -635,7 +678,7 @@ def safe_markup(raw_html):
635678 )
636679
637680
638- def safe_text (raw_text ) :
681+ def safe_text (raw_text : str ) -> jinja2 . Markup :
639682 """
640683 Process text: treat it as HTML but escape any tags (ie. just escape the
641684 HTML) then linkify it.
@@ -655,7 +698,7 @@ def deduped_ordered_list(it: Iterable[T]) -> List[T]:
655698 return ret
656699
657700
658- def string_ordinal_total (s ) :
701+ def string_ordinal_total (s : str ) -> int :
659702 tot = 0
660703 for c in s :
661704 tot += ord (c )
0 commit comments