@@ -116,6 +116,32 @@ def gather_countries_and_regions(self, records):
116116 countries = ["c%s" % id for id in countries ]
117117 return countries , regions
118118
119+ def gather_event_countries_and_regions (self , records ):
120+ # Applies to surgealerts, which have a
121+ # many-to-many relationship to countries and regions through event table
122+ countries = []
123+ for record in records :
124+ if record .event .countries is not None :
125+ countries += [country .id for country in record .event .countries .all ()]
126+ countries = list (set (countries ))
127+ qs = Country .objects .filter (pk__in = countries )
128+ regions = ["r%s" % country .region .id for country in qs if country .region is not None ]
129+ countries = ["c%s" % id for id in countries ]
130+ return countries , regions
131+
132+ def gather_eventdt_countries_and_regions (self , records ):
133+ # Applies to deployments_personneldeployments, which have a
134+ # many-to-many relationship to countries and regions through event_deployed_to
135+ countries = []
136+ for record in records :
137+ if record .event_deployed_to .countries is not None :
138+ countries += [country .id for country in record .event_deployed_to .countries .all ()]
139+ countries = list (set (countries ))
140+ qs = Country .objects .filter (pk__in = countries )
141+ regions = ["r%s" % country .region .id for country in qs if country .region is not None ]
142+ countries = ["c%s" % id for id in countries ]
143+ return countries , regions
144+
119145 def fix_types_for_subs (self , rtype , stype = SubscriptionType .NEW ):
120146 # Correction for the new notification types:
121147 if rtype == RecordType .EVENT or rtype == RecordType .FIELD_REPORT :
@@ -133,34 +159,68 @@ def gather_subscribers(self, records, rtype, stype):
133159 if self .is_digest_mode ():
134160 subscribers = User .objects .filter (subscription__rtype = RecordType .WEEKLY_DIGEST , is_active = True ).values ("email" )
135161 # In digest mode we do not care about other circumstances, just get every subscriber's email.
136- emails = [subscriber ["email" ] for subscriber in subscribers ]
162+ emails = list ( set ( [subscriber ["email" ] for subscriber in subscribers ]))
137163 return emails
138164 else :
139165 # Start with any users subscribed directly to this record type.
140166 subscribers = User .objects .filter (
141167 subscription__rtype = rtype_of_subscr , subscription__stype = stype , is_active = True
142168 ).values ("email" )
169+ emails = list (set ([subscriber ["email" ] for subscriber in subscribers ]))
170+
171+ # For FOLLOWED_EVENTs we do not collect other generic (d*, country, region) subscriptions.
172+ if rtype_of_subscr != RecordType .FOLLOWED_EVENT :
173+ subscribers_no_geo_dtype = (
174+ User .objects .filter (subscription__rtype = rtype_of_subscr , subscription__stype = stype , is_active = True )
175+ .exclude (subscription__rtype__in = [RecordType .COUNTRY , RecordType .REGION , RecordType .DTYPE ])
176+ .values ("email" )
177+ )
178+ emailset_no_geo_dtype = {subscriber ["email" ] for subscriber in subscribers_no_geo_dtype }
143179
144- # For FOLLOWED_EVENTs and DEPLOYMENTs we do not collect other generic (d*, country, region) subscriptions, just one.
145- # This part is not called.
146- if (
147- rtype_of_subscr != RecordType .FOLLOWED_EVENT
148- and rtype_of_subscr != RecordType .SURGE_ALERT
149- and rtype_of_subscr != RecordType .SURGE_DEPLOYMENT_MESSAGES
150- ):
151- dtypes = list (set (["d%s" % record .dtype .id for record in records if record .dtype is not None ]))
180+ subscribers_geo = (
181+ User .objects .filter (subscription__rtype = rtype_of_subscr , subscription__stype = stype , is_active = True )
182+ .filter (subscription__rtype__in = [RecordType .COUNTRY , RecordType .REGION ])
183+ .values ("email" )
184+ )
185+ emailset_geo = {subscriber ["email" ] for subscriber in subscribers_geo }
186+
187+ subscribers_dtype = (
188+ User .objects .filter (subscription__rtype = rtype_of_subscr , subscription__stype = stype , is_active = True )
189+ .filter (subscription__rtype = RecordType .DTYPE )
190+ .values ("email" )
191+ )
192+ emailset_dtype = {subscriber ["email" ] for subscriber in subscribers_dtype }
152193
153194 if rtype_of_subscr == RecordType .NEW_OPERATIONS :
154195 countries , regions = self .gather_country_and_region (records )
196+ elif rtype_of_subscr == RecordType .SURGE_ALERT :
197+ countries , regions = self .gather_event_countries_and_regions (records )
198+ elif rtype_of_subscr == RecordType .SURGE_DEPLOYMENT_MESSAGES :
199+ countries , regions = self .gather_eventdt_countries_and_regions (records )
155200 else :
156201 countries , regions = self .gather_countries_and_regions (records )
157202
158- lookups = dtypes + countries + regions
159- if len (lookups ):
160- subscribers = (
161- subscribers | User .objects .filter (subscription__lookup_id__in = lookups , is_active = True ).values ("email" )
162- ).distinct ()
163- emails = list (set ([subscriber ["email" ] for subscriber in subscribers ]))
203+ if rtype_of_subscr == RecordType .SURGE_ALERT :
204+ dtypes = list (set (["d%s" % record .event .dtype .id for record in records if record .event .dtype is not None ]))
205+ elif rtype_of_subscr == RecordType .SURGE_DEPLOYMENT_MESSAGES :
206+ dtypes = list (set (["d%s" % rec .event_deployed_to .dtype .id for rec in records if rec .event_deployed_to .dtype ]))
207+ else :
208+ dtypes = list (set (["d%s" % record .dtype .id for record in records if record .dtype is not None ]))
209+
210+ geo = countries + regions
211+ if len (geo ):
212+ emailset_geo = emailset_geo & {
213+ subscriber ["email" ]
214+ for subscriber in User .objects .filter (subscription__lookup_id__in = geo , is_active = True ).values ("email" )
215+ }
216+
217+ if len (dtypes ):
218+ emailset_dtype = emailset_dtype & {
219+ subscriber ["email" ]
220+ for subscriber in User .objects .filter (subscription__lookup_id__in = dtypes , is_active = True ).values ("email" )
221+ }
222+
223+ emails = list (emailset_no_geo_dtype | emailset_geo | emailset_dtype )
164224 return emails
165225
166226 def get_template (self , rtype = 99 ):
0 commit comments