def test_create_first_sends_email(self): """If, on POST, user is captain of one ep team, they get an email.""" captain_first = User.create(name='foo', email='*****@*****.**') captain_first.put() # Demo program doesn't trigger any emails. team_params = {'name': 'Demo 1', 'program_id': self.demo_program.uid} self.testapp.post_json( '/api/teams', team_params, headers=self.login_headers(captain_first), ) self.assertEqual(Email.count(), 0) # First team created for EP sends email (even though they have a team # on another program). team_params = {'name': 'EP 1', 'program_id': self.ep_program.uid} result1 = self.testapp.post_json( '/api/teams', team_params, headers=self.login_headers(captain_first), ) self.assertEqual(Email.count(), 1) email1 = Email.get()[0] self.assertEqual(email1.template, 'ep19/welcome.html') self.assertEqual(email1.to_address, captain_first.email) # User who already is on another team, but isn't captain, then creates # a team, gets the email. team1_id = json.loads(result1.body)['uid'] member_first = User.create(name="Member", email="*****@*****.**", owned_teams=[team1_id]) member_first.put() team_params = {'name': 'EP 2', 'program_id': self.ep_program.uid} result2 = self.testapp.post_json( '/api/teams', team_params, headers=self.login_headers(member_first), ) email2 = next(e for e in Email.get() if e.to_address == member_first.email) self.assertEqual(email2.template, 'ep19/welcome.html') # User who creates a second team doesn't get the email. team_params = {'name': 'EP 3', 'program_id': self.ep_program.uid} result3 = self.testapp.post_json( '/api/teams', team_params, headers=self.login_headers(captain_first), ) captain_first_emails = [e for e in Email.get() if e.to_address == captain_first.email] # Only the first email is there, no second email. self.assertEqual(len(captain_first_emails), 1)
def test_spam_with_single_email(self): # Create a single email to_address = '' email = self.admin_api.create('Email', to_address=to_address) Email.send_pending_email() fetched_email = Email.query(Email.to_address == to_address).get() self.assertIsInstance(fetched_email, Email) # Test if email was attempted to send self.assertEqual(fetched_email.was_attempted, True) # ...and has been sent self.assertEqual(fetched_email.was_sent, True)
def test_put_artifact_url_sends_email(self): """PUT response has special jwt giving permission on Neptune.""" user = User.create(name='foo', email='*****@*****.**') team = Team.create(name="Foo Team", captain_id=user.uid, program_id="Program_foo") survey = Survey.create(team_id=team.uid) user.owned_teams = [team.uid] team.put() survey.put() user.put() artifact_url = 'https://www.example.com/artifact' # Not changing the artifact does NOT trigger an email. self.testapp.put_json( '/api/surveys/{}'.format(survey.uid), {'meta': { 'artifact_url': '' }}, headers=self.login_headers(user), ) self.assertEqual(Email.count(), 0) # Changing it triggers an email. self.testapp.put_json( '/api/surveys/{}'.format(survey.uid), {'meta': { 'artifact_use': 'true', 'artifact_url': artifact_url }}, headers=self.login_headers(user), ) emails = Email.get() self.assertEqual(len(emails), 1) email = emails[0] self.assertIn(artifact_url, email.html) self.assertIn(team.name, email.html) # Sending a PUT **without** changing it does NOT trigger an email. self.testapp.put_json( '/api/surveys/{}'.format(survey.uid), {'meta': { 'artifact_use': 'true', 'artifact_url': artifact_url }}, headers=self.login_headers(user), ) self.assertEqual(Email.count(), 1) # same as before
def test_spam_with_single_email(self): # Create a single email to_address = '*****@*****.**' email = Email.create(to_address=to_address) email.put() Email.send_pending_email() fetched_email = Email.query(Email.to_address == to_address).get() self.assertIsInstance(fetched_email, Email) # Test if email was attempted to send self.assertEqual(fetched_email.was_attempted, True) # ...and has been sent self.assertEqual(fetched_email.was_sent, True)
def test_comment_creates_email(self): # Create a comment on a new practice practice = self.normal_api.create( 'Practice', name=u'Spam Checker', summary=u"This is a summary for the practice", body=u"This is the body of the practice", pending=False, listed=True, ) commenter = self.admin_api.create( 'User', email='unit_testing+', auth_id='own:unit_testing+', first_name='Commenting', last_name='User', ) commenter_api = Api(commenter) comment = commenter_api.create( 'Comment', body='Wow, what a great practice.', practice_id=practice.uid, ) fetched_email = Email.query().get() # The email is about the posted comment... self.assertEqual(fetched_email.template_data['comment_body'], comment.body) # ...and is going to the owner of the practice. self.assertEqual(fetched_email.to_address, self.normal_user.email)
def post(self, project_id, slug): """A project has been identified as new. Send them a welcome.""" project = Project.get_by_id(project_id) program = Program.get_config(project.program_label) org = Organization.get_by_id(project.organization_id) # The Org liaison is preferred, but is not guaranteed to be set (users # choose their org liaison explicitly as one of the org tasks). Default # to the Project liaison, which is set on creation in # add_program.controller.js@joinProgram org_liaison = User.get_by_id(org.liaison_id) project_liaison = User.get_by_id(project.liaison_id) liaison = org_liaison or project_liaison email = Email.create( to_address=liaison.email, mandrill_template=slug, mandrill_template_content={ 'program_name': program['name'], 'organization_name': org.name, 'liaison_name': liaison.name, 'join_date': util.datelike_to_iso_string(project.created), }, ) email.put()
def test_spam_with_two_emails_to_same_address(self): # Create a single email to_address = '' email = self.admin_api.create('Email', to_address=to_address) second_email = self.admin_api.create('Email', to_address=to_address) Email.send_pending_email() fetched_email = Email.query().fetch() self.assertEqual(len(fetched_email), 2) self.assertIsInstance(fetched_email[0], Email) self.assertIsInstance(fetched_email[1], Email) # Test if email was attempted to send self.assertEqual(fetched_email[0].was_attempted, True) self.assertEqual(fetched_email[1].was_attempted, True) # ...and has been sent self.assertEqual(fetched_email[0].was_sent, True) self.assertEqual(fetched_email[1].was_sent, False)
def send_email_to_bpm(recipients, subject, text, to, files): json_email = { 'mail_from': recipients['From'], 'mail_to': to, 'subject': subject, 'body': text, 'mail_cc': recipients['Cc'], 'files': files } return Email.from_dict(json_email).save()
def get_payload_headers(gmail_service, query): """List Messages of the user's inbox matching the query.""" try: results = gmail_service.users().messages().list(userId='me', q=query).execute() msgs = results.get('messages', []) headers_dict = {} for msg in msgs: message_id_headers = { } #this dict is used to add the msg id as the key to the message dict payload_headers message_info = get_message_by_id(gmail_service, 'me', msg['id']) #msg ids and threadids message_id = str(message_info['id']) header_dict = {} payload_headers = message_info['payload']['headers'] message_id_headers[message_id] = payload_headers for key, value in message_id_headers.items(): for dict_items in value: key = dict_items['name'] value = dict_items['value'] if key in [ 'Subject', 'From', 'Date' ]: #This is only grabbing 1 message instead of all messages header_dict[key] = value for key in message_id_headers: headers_dict[key] = header_dict date_str = header_dict['Date'] From = header_dict['From'] Subject = header_dict['Subject'] msg_id = key emailpresentindb = db.session.query(Email).filter( Email.email_id == msg_id).first() if emailpresentindb is None: message = Email(email_id=msg_id, subject=Subject, sender_email=From, received_at=date_str) db.session.add(message) db.session.commit() header_dict['Email'] = db.session.query(Email).filter( Email.email_id == msg_id).first() return headers_dict except errors.HttpError, error: print 'An error occurred: %s' % error
def test_spam_with_two_emails_to_different_addresses(self): # Create a single email to_address = '*****@*****.**' second_address = '*****@*****.**' email = Email.create(to_address=to_address) email.put() second_email = Email.create(to_address=second_address) second_email.put() Email.send_pending_email() fetched_email = Email.query().fetch() self.assertEqual(len(fetched_email), 2) self.assertIsInstance(fetched_email[0], Email) self.assertIsInstance(fetched_email[1], Email) # Test if email was attempted to send self.assertEqual(fetched_email[0].was_attempted, True) self.assertEqual(fetched_email[1].was_attempted, True) # ...and has been sent self.assertEqual(fetched_email[0].was_sent, True) self.assertEqual(fetched_email[1].was_sent, True)
def test_spam_with_recent_email_to_same_addresses(self): # Create a sent and not sent email to same address # Note: Cannot be to a '@mindsetkit.org' address to_address = '' email_subject = 'Email subject' sent_email = self.admin_api.create('Email', to_address=to_address, was_attempted=True, was_sent=True) email = self.admin_api.create('Email', to_address=to_address, subject=email_subject) Email.send_pending_email() fetched_email = Email.query(Email.subject == email_subject).get() self.assertIsInstance(fetched_email, Email) # Test if email was attempted to send self.assertEqual(fetched_email.was_attempted, True) # ...and has been sent self.assertEqual(fetched_email.was_sent, False)
def index(): if request.method == "POST": if not Email.get_or_none(Email.email == request.form['email']): if EMAIL_REGEX.match(request.form["email"]): Email.create( email=request.form["email"], timestamp=datetime.datetime.now(), ) flash("The email address you entered ({}) \ \nis a VALID email address! Thank you!".format( request.form['email'])) return redirect("/success") else: flash("Email is not valid!") else: flash("Email already exists!") return render_template('index.html')
def index(): if request.method == "POST": if not Email.get_or_none(Email.email == request.form['email']): if EMAIL_REGEX.match(request.form["email"]): Email.create( email=request.form["email"], timestamp=datetime.datetime.now(), ) flash("The email address you entered ({}) \ \nis a VALID email address! Thank you!".format( request.form['email'])) return redirect("/success") else: flash("Email is not valid!") else: flash("Email already exists!") return render_template('index.html')
def test_create_first_sends_email(self): """If, on POST, user is admin of one Elevate org, they get an email.""" admin_first = User.create(name='foo', email='*****@*****.**') admin_first.put() # Creating an org in EP doesn't trigger any emails. org_params = {'name': 'EP 1', 'program_id': self.program.uid} self.testapp.post_json( '/api/organizations', org_params, headers=self.login_headers(admin_first), ) self.assertEqual(Email.count(), 0) # First org created for BELESET sends email (even though they have an # org in another program). org_params1 = {'name': 'Org 1', 'program_id': self.beleset_program.uid} result1 = self.testapp.post_json( '/api/organizations', org_params1, headers=self.login_headers(admin_first), ) self.assertEqual(Email.count(), 1) email1 = Email.get()[0] self.assertEqual(email1.template, 'beleset19/welcome.html') self.assertIn(admin_first.email, email1.to_address) # User who creates a second org doesn't get the email. org_params2 = {'name': 'Org 2', 'program_id': self.beleset_program.uid} result2 = self.testapp.post_json( '/api/organizations', org_params2, headers=self.login_headers(admin_first), ) # Only the first email is there, no second email. self.assertEqual(Email.count(), 1)
def test_spam_with_recent_email_to_different_addresses(self): # Create a sent and not sent email to different addresses # Note: Cannot be to a '@mindsetkit.org' address to_address = '*****@*****.**' second_address = '*****@*****.**' email_subject = 'Email subject' sent_email = Email.create( to_address=to_address, was_attempted=True, was_sent=True,) sent_email.put() email = Email.create( to_address=second_address, subject=email_subject) email.put() Email.send_pending_email() fetched_email = Email.query(Email.subject == email_subject).get() self.assertIsInstance(fetched_email, Email) # Test if email was attempted to send self.assertEqual(fetched_email.was_attempted, True) # ...and has been sent self.assertEqual(fetched_email.was_sent, True)
def after_put(self, init_kwargs, *args, **kwargs): is_using = self.meta.get('artifact_use', None) == 'true' url = self.meta.get('artifact_url', None) is_different = init_kwargs['meta'].get('artifact_url', None) != url if is_using and url and is_different: team = Team.get_by_id(self.team_id) team_url = 'https://copilot.perts.net/teams/{}'.format( team.short_uid) Email.create( to_address=config.from_server_email_address, subject=(u"Message IT artifact URL needs review: {}".format( team.name)), html=u''' <p>Team name: <a href="{team_url}">{team_name}</a></p> <p> Artifact URL: <a href="{artifact_url}">{artifact_url}</a> </p> '''.format( team_name=team.name, artifact_url=self.meta['artifact_url'], team_url=team_url, ), ).put()
def setUp(self): """Setup a test database and insert a dummy record.""" DBSession = sessionmaker(bind=test_engine) Base.metadata.create_all(test_engine) session = DBSession() email_obj = Email(from_address="*****@*****.**", to_address="*****@*****.**", is_read=True, is_archived=True, subject="test", message_body="test", message_id="test", label="INBOX", has_attachment=False, received_on=datetime.now()) session.add(email_obj) session.commit()
def save_new_email_ids(email_ids): """Receives a list of email_ids (dictionaries), and saves new email objects to the database.""" new_ids = [] for email_id in email_ids: # If email id already exists, don't add it to the list try: email = db_session.query(Email).filter_by( gmail_id=email_id['id']).one() # If it doesn't already exist, add it to the database and the new # ids list except sqlalchemy.orm.exc.NoResultFound, e: email = Email(gmail_id=email_id['id'], thread_id=email_id['threadId'], belongs_to=session['user_id']) db_session.add(email) new_ids.append(email_id)
def email_list_to_database() -> None: """ Get all the email objects from the Gmail API and parses it to get the required fields and store it in the local database. :return: None """ try: session.query(Email).delete() session.commit() bar = Bar('Processing', max=TOTAL_PAGES_TO_READ * MAX_RESULTS_PER_PAGE) service = api.get_gmail_service() all_emails = api.get_all_mails_from_gmail() all_labels = api.list_user_labels() for email in all_emails: message = api.get_message(user_id="me", msg_id=email['id'], service=service) payload = message['payload'] temp_dict = parse_message_headers(headers=payload['headers']) message_body, attachment = parse_message_payload(payload=payload) temp_dict['message_body'] = re.sub(r'[\t\r\n]', '', message_body) temp_dict['has_attachment'] = attachment temp_dict['message_id'] = message['id'] message['labelIds'] = convert_label_id( email_labels=message["labelIds"], all_labels=all_labels) temp_dict['label'] = ','.join(message['labelIds']) if 'INBOX' not in message['labelIds']: temp_dict['is_archived'] = True else: temp_dict['is_archived'] = False if 'UNREAD' in message['labelIds']: temp_dict['is_read'] = False else: temp_dict['is_read'] = True email_obj = Email(**temp_dict) session.add(email_obj) session.commit() bar.next() bar.finish() print("Successfully dumped email to database!") except (SQLAlchemyError, errors.HttpError) as e: print(f"Database Syncing failed. Error is : {e}")
def test_sends_correct_email_for_ep(self, *args): # Note that what this handler should do if there isn't a current cycle # is tested in test_surveys.TestSurveys.test_should_notify program, captain, team, classrooms, cycle = self.create('ep19') # Mock Neptune's participation API. class MockFetchResult(object): status_code = 200 content = r'{}' with patch.object(urlfetch, 'fetch', return_value=MockFetchResult()) as _: handler = task_handlers.TeamCycleEmails() # Run the task. handler.post(team.uid) emails = Email.get() self.assertEqual(len(emails), 1) self.assertIn('ep19-cycle-progress-email', emails[0].html)
def get_email(self, to_address): template = jinja_env.get_template('notifications/digest_email.html') return Email.create(to_address=to_address, subject=self.subject, html=template.render(body=self.body))
def remove(email): Email.delete().where(Email.email == email).execute() return redirect("/success")
def success(): emails = Email.select() return render_template("success.html", emails=emails)
def send_pending_email(self): """Send any email in the queue. Must be called with internal_api for full permissions. See id_model@Email for full description. """ return Email.send_pending_email()
def remove(email): Email.delete().where(Email.email == email).execute() return redirect("/success")
def success(): emails = Email.select() return render_template("success.html", emails=emails)
def row_to_email(row): return Email(row[0], row[1], row[2], row[3])
def create_ep_email( program_label, recipient, users, team, classrooms, responses, cycle, pct_complete_by_id, ): """Render a cycle reminder email. Args: program_label, e.g. 'ep19' recipient - User users - all Users on the team team - Team classrooms - Classrooms, all on the team responses - All responses from the team, with no bodies cycle - Cycle, current pct_complete_by_id - dict, {classroom_id: int} Returns: html string """ if team.captain_id == recipient.uid: user_classrooms = classrooms else: user_classrooms = [ c for c in classrooms if recipient.uid == c.contact_id ] # EP Journals are always user-level. ids_with_responses = [r.user_id for r in responses if r.user_id] journal_statuses = [{ 'user_id': u.uid, 'user_name': u.name, 'status': ('Complete' if u.uid in ids_with_responses else 'Incomplete'), } for u in users] own_journal_status = next(d for d in journal_statuses if d['user_id'] == recipient.uid)['status'] params = { 'user': recipient, 'is_captain': recipient.uid == team.captain_id, 'team': team, 'classrooms': user_classrooms, 'copilot_url': 'https://{}'.format(os.environ['HOSTING_DOMAIN']), 'cycle': cycle, 'pct_complete_by_id': pct_complete_by_id, 'journal_complete': own_journal_status == 'Complete', 'journal_statuses': journal_statuses, } # Why not send these the "normal" way, where we pass the template # file name and the template params into the Email entity? Because this # is a case where the parameters are quite large and non-trivial to # serialize to JSON for storage. Simpler to reduce the incoming data # to the rendered html body and store that in the entity. template = jinja_env.get_template( '{}/cycle_progress.html'.format(program_label)) return Email.create(to_address=recipient.email, subject="Engagement Project: Progress Update", html=template.render(**params))
def get(self): emails = Email.send_pending_email() self.write(emails)