Skip to content

Commit

Permalink
SDAN-713 Add the ability to add an email address to a Monitoring prof…
Browse files Browse the repository at this point in the history
…ile (#1159)
  • Loading branch information
marwoodandrew authored Feb 28, 2022
1 parent af82ad6 commit 261dc25
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 4 deletions.
9 changes: 9 additions & 0 deletions assets/monitoring/components/EditMonitoringProfile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@ class EditMonitoringProfile extends React.Component {
onChange={onChange}
error={getError('company')} />

<TextInput
name='email'
label={gettext('Email Address')}
value={item.email || ''}
onChange={onChange}
error={getError('email')}
description={gettext('Optional comma seperated list of email addresses')}
/>

<TextAreaInput
name='query'
label={gettext('Query')}
Expand Down
1 change: 1 addition & 0 deletions assets/monitoring/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export default function monitoringReducer(state = initialState, action) {
name: '',
subject: '',
description: '',
email: '',
alert_type: 'full_text',
format_type: 'monitoring_pdf',
company: '',
Expand Down
16 changes: 13 additions & 3 deletions newsroom/monitoring/email_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from .utils import get_monitoring_file, truncate_article_body, get_date_items_dict
import base64
import os
import re

try:
from urllib.parse import urlparse
Expand Down Expand Up @@ -241,13 +242,22 @@ def already_sent(self, item, profile):

def filter_users(self, m, company):
"""
return a list of users from the profile that are enabled and belong to the company the profile belongs to.
return a list of users email addresses from the profile that are enabled and belong to the company the
profile belongs to. It will also add any email addresses that may be associated with the profile if are
available and are unique
:param m:
:param company:
:return: List of valid users
"""
return [email['email'] for email in [u for u in get_items_by_id([ObjectId(u) for u in m['users']], 'users') if
u['is_enabled'] and u['company'] == company['_id']]]
email_addresses = [email['email'] for email in
[u for u in get_items_by_id([ObjectId(u) for u in m['users']], 'users') if
u['is_enabled'] and u['company'] == company['_id']]]
# append any addresses from the profile
if m.get('email'):
for address in re.split(r'[, ]*', m.get('email')):
if m.get('email') not in email_addresses:
email_addresses.append(address)
return email_addresses

def send_alerts(self, monitoring_list, created_from, created_from_time, now):
general_settings = get_settings_collection().find_one(GENERAL_SETTINGS_LOOKUP)
Expand Down
14 changes: 13 additions & 1 deletion newsroom/monitoring/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
from flask_babel import gettext
from wtforms import StringField, HiddenField, BooleanField, TextAreaField
from wtforms import SelectField
from wtforms.validators import DataRequired
from wtforms.validators import DataRequired, Email, Optional
from copy import deepcopy
import re

alert_types = [('full_text', gettext('Full text')), ('linked_text', gettext('Linked extract(s)'))]
format_types = [('monitoring_pdf', gettext('PDF')), ('monitoring_rtf', gettext('RTF')),
Expand All @@ -22,8 +24,18 @@ class Meta:
alert_type = SelectField(gettext('Alert Type'), choices=alert_types, default='full_text')
format_type = SelectField(gettext('Format Type'), choices=format_types, default='monitoring_pdf')
company = StringField(gettext('Company'), validators=[DataRequired()])
email = StringField(gettext('Email'), validators=[Optional()], default='')
is_enabled = BooleanField(gettext('Enabled'), default=True, validators=[])
always_send = BooleanField(gettext('Always Send'), default=False, validators=[])
headline_subject = BooleanField(gettext('Use Headline as Subject of emails containing a single item'),
default=False, validators=[])
query = TextAreaField(gettext('Query'))

def validate_email(form, field):
address_list = re.split(r'[, ]*', field.data)
input_data = deepcopy(field.data)
for address in address_list:
v = Email(message=field.gettext('Invalid email address: ') + address)
field.data = address
v(form, field)
field.data = input_data
6 changes: 6 additions & 0 deletions newsroom/monitoring/monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ class MonitoringResource(newsroom.Resource):
'company': {
'type': 'objectid'
},
# Additional email addresses to send the monitoring email to, They do not need to belong to a newsroom user,
# they are intended to usually belong to a distribution list of the client company
'email': {
'type': 'string',
'nullable': True
},
'query': {
'type': 'string'
},
Expand Down
3 changes: 3 additions & 0 deletions newsroom/monitoring/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def process_form_request(updates, request_updates, form):
if 'keywords' in request_updates:
updates['keywords'] = request_updates['keywords']

if 'email' in request_updates:
updates['email'] = request_updates.get('email').replace(' ', '')


def get_monitoring_for_company(user):
company = user['company'] if user and user.get('company') else None
Expand Down
23 changes: 23 additions & 0 deletions tests/test_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,3 +948,26 @@ def test_save_only_users_belonging_to_company(client, app):
}), content_type='application/json')
m = app.data.find_one('monitoring', None, _id="5db11ec55f627d8aa0b545fb")
assert m['users'] == [ObjectId("5c53afa45f627d8333220f15")]


@mock.patch('newsroom.monitoring.email_alerts.utcnow', mock_utcnow)
@mock.patch('newsroom.email.send_email', mock_send_email)
def test_send_profile_email(client, app):
test_login_succeeds_for_admin(client)
app.data.insert('items', [{
'_id': 'foo',
'headline': 'product immediate',
'products': [{'code': '12345'}],
"versioncreated": utcnow(),
'byline': 'Testy McTestface',
'body_html': '<p>line 1 of the article text\nline 2 of the story\nand a bit more.</p>',
'source': 'AAAA'
}])
m = app.data.find_one('monitoring', None, _id="5db11ec55f627d8aa0b545fb")
assert m is not None
app.data.update('monitoring', ObjectId("5db11ec55f627d8aa0b545fb"), {'email': '[email protected], [email protected]'}, m)
with app.mail.record_messages() as outbox:
MonitoringEmailAlerts().run(immediate=True)
assert len(outbox) == 1
assert '[email protected]' in outbox[0].recipients
assert '[email protected]' in outbox[0].recipients

0 comments on commit 261dc25

Please sign in to comment.