Exemplo n.º 1
0
def handle_similar_users(message):
    """ Save the similar users data to the DB
    """

    if current_app.config['TESTING']:
        return

    user_count, avg_similar_users, error = import_user_similarities(
        message['data'])
    if error:
        send_mail(
            subject='Similar User data failed to be calculated',
            text=render_template(
                'emails/similar_users_failed_notification.txt', error=error),
            recipients=['*****@*****.**'],
            from_name='ListenBrainz',
            from_addr='noreply@' + current_app.config['MAIL_FROM_DOMAIN'],
        )
    else:
        send_mail(
            subject='Similar User data has been calculated',
            text=render_template(
                'emails/similar_users_updated_notification.txt',
                user_count=str(user_count),
                avg_similar_users="%.1f" % avg_similar_users),
            recipients=['*****@*****.**'],
            from_name='ListenBrainz',
            from_addr='noreply@' + current_app.config['MAIL_FROM_DOMAIN'],
        )
Exemplo n.º 2
0
    def test_send_email(self, mock_smtp):
        app = flask.CustomFlask(__name__)
        app.config['SMTP_SERVER'] = 'localhost'
        app.config['SMTP_PORT'] = 25

        with app.app_context():
            from_address = '*****@*****.**'
            recipients = [
                '*****@*****.**', '*****@*****.**'
            ]
            text = 'It is a test mail'
            from_name = 'ListenBrainz'
            subject = 'ListenBrainz Spotify Importer Error'
            boundary = '===============2220963697271485568=='
            message = MIMEMultipart(boundary=boundary)
            message[
                'To'] = "[email protected], [email protected]"
            message['Subject'] = subject
            message['From'] = '%s <%s>' % (from_name, from_address)
            message.attach(MIMEText(text, _charset='utf-8'))

            mail.send_mail(subject='ListenBrainz Spotify Importer Error',
                           text='It is a test mail',
                           recipients=recipients,
                           attachments=None,
                           from_name='ListenBrainz',
                           from_addr='*****@*****.**',
                           boundary=boundary)

            mock_smtp.return_value.sendmail.assert_called_once_with(
                from_address, recipients, message.as_string())
Exemplo n.º 3
0
def notify_user_stats_update(stat_type):
    if not current_app.config['TESTING']:
        send_mail(
            subject="New user stats are being written into the DB - ListenBrainz",
            text=render_template('emails/user_stats_notification.txt', now=str(datetime.utcnow()), stat_type=stat_type),
            recipients=['*****@*****.**'],
            from_name='ListenBrainz',
            from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN']
        )
Exemplo n.º 4
0
def send_dump_creation_notification(dump_name, dump_type):
    if not current_app.config['TESTING']:
        dump_link = 'http://ftp.musicbrainz.org/pub/musicbrainz/listenbrainz/{}/{}'.format(dump_type, dump_name)
        send_mail(
            subject="ListenBrainz dump created - {}".format(dump_name),
            text=render_template('emails/data_dump_created_notification.txt', dump_name=dump_name, dump_link=dump_link),
            recipients=['*****@*****.**'],
            from_name='ListenBrainz',
            from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN']
        )
Exemplo n.º 5
0
 def test_send_email_string_recipients(self):
     app = flask.CustomFlask(__name__)
     with app.app_context():
         with self.assertRaises(ValueError) as err:
             mail.send_mail(subject='ListenBrainz Spotify Importer Error',
                            text='It is a test mail',
                            recipients='*****@*****.**',
                            attachments=None,
                            from_name='ListenBrainz',
                            from_addr='*****@*****.**',
                            boundary='b')
         assert str(err.exception
                    ) == "recipients must be a list of email addresses"
Exemplo n.º 6
0
 def test_send_email_missing_config(self):
     app = flask.CustomFlask(__name__)
     with app.app_context():
         with self.assertRaises(ValueError) as err:
             mail.send_mail(subject='ListenBrainz Spotify Importer Error',
                            text='It is a test mail',
                            recipients=[],
                            attachments=None,
                            from_name='ListenBrainz',
                            from_addr='*****@*****.**',
                            boundary='b')
         assert "Flask current_app requires config items" in str(
             err.exception)
def notify_cf_recording_recommendations_update():
    """ Send an email to notify recommendations are being written into db.
    """
    if current_app.config['TESTING']:
        return

    send_mail(
        subject="Recommendations being written into the DB - ListenBrainz",
        text=render_template(
            'emails/cf_recording_recommendation_notification.txt',
            now=str(datetime.utcnow())),
        recipients=['*****@*****.**'],
        from_name='ListenBrainz',
        from_addr='noreply@' + current_app.config['MAIL_FROM_DOMAIN'])
Exemplo n.º 8
0
def notify_mapping_import(data):
    """ Send an email after msid mbid mapping has been successfully imported into the cluster.
    """
    if current_app.config['TESTING']:
        return

    mapping_name = data['imported_mapping']
    import_completion_time = data['time']
    send_mail(
        subject='MSID MBID mapping has been imported into the Spark cluster',
        text=render_template('emails/mapping_import_notification.txt', mapping_name=mapping_name, time=import_completion_time),
        recipients=['*****@*****.**'],
        from_name='ListenBrainz',
        from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN'],
    )
Exemplo n.º 9
0
def handle_model(data):
    """ Send an email after trained data (model) has been successfully uploaded to HDFS.
    """
    if current_app.config['TESTING']:
        return

    model_upload_time = data['model_upload_time']
    model_creation_time = data['total_time']
    send_mail(
        subject='Model created and successfully uploaded to HDFS',
        text=render_template('emails/cf_recording_model_upload_notification.txt', time_to_upload=model_upload_time,
                             total_time=model_creation_time),
        recipients=['*****@*****.**'],
        from_name='ListenBrainz',
        from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN'],
    )
Exemplo n.º 10
0
def handle_dump_imported(data):
    """ Process the response that the cluster sends after importing a new dump

    We don't really need to _do_ anything, just send an email over for observability.
    """
    if current_app.config['TESTING']:
        return

    dump_name = data['imported_dump']
    import_completion_time = data['time']
    send_mail(
        subject='A {} has been imported into the Spark cluster'.format(' '.join(data['type'].split('_')[1:])),
        text=render_template('emails/dump_import_notification.txt', dump_name=", ".join(dump_name), time=import_completion_time),
        recipients=['*****@*****.**'],
        from_name='ListenBrainz',
        from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN'],
    )
def notify_error(musicbrainz_row_id, error):
    """ Notifies specified user via email about error during Spotify import.

    Args:
        musicbrainz_row_id (int): the MusicBrainz row ID of the user
        error (str): a description of the error encountered.
    """
    user_email = mb_editor.get_editor_by_id(musicbrainz_row_id)['email']
    spotify_url = current_app.config['SERVER_ROOT_URL'] + '/profile/connect-spotify'
    text = render_template('emails/spotify_import_error.txt', error=error, link=spotify_url)
    send_mail(
        subject='ListenBrainz Spotify Importer Error',
        text=text,
        recipients=[user_email],
        from_name='ListenBrainz',
        from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN'],
    )
Exemplo n.º 12
0
def handle_candidate_sets(data):
    """ Send an email after candidate sets have been successfully uploaded to HDFS.
    """
    if current_app.config['TESTING']:
        return

    candidate_sets_upload_time = data['candidate_sets_upload_time']
    candidate_set_creation_time = data['total_time']
    from_date = data['from_date']
    to_date = data['to_date']
    send_mail(
        subject='Candidate sets created and successfully uploaded to HDFS',
        text=render_template('emails/cf_candidate_sets_upload_notification.txt', time_to_upload=candidate_sets_upload_time,
                             from_date=from_date, to_date=to_date, total_time=candidate_set_creation_time),
        recipients=['*****@*****.**'],
        from_name='ListenBrainz',
        from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN'],
    )
Exemplo n.º 13
0
def check_ftp_dump_ages():
    """
        Fetch the FTP dir listing of the full and incremental dumps and check their ages. Send mail
        to the observability list in case the dumps are too old.
    """

    msg = ""
    try:
        id, dt = _fetch_latest_file_info_from_ftp_dir(
            MAIN_FTP_SERVER_URL, '/pub/musicbrainz/listenbrainz/fullexport')
        age = datetime.now() - dt
        if age > timedelta(days=FULLEXPORT_MAX_AGE):
            msg = "Full dump %d is more than %d days old: %s\n" % (
                id, FULLEXPORT_MAX_AGE, str(age))
            print(msg, end="")
        else:
            print("Full dump %s is %s old, good!" % (id, str(age)))
    except Exception as err:
        msg = "Cannot fetch full dump age: %s" % str(err)

    try:
        id, dt = _fetch_latest_file_info_from_ftp_dir(
            MAIN_FTP_SERVER_URL, '/pub/musicbrainz/listenbrainz/incremental')
        age = datetime.now() - dt
        if age > timedelta(hours=INCREMENTAL_MAX_AGE):
            msg = "Incremental dump %s is more than %s hours old: %s\n" % (
                id, INCREMENTAL_MAX_AGE, str(age))
            print(msg, end="")
        else:
            print("Incremental dump %s is %s old, good!" % (id, str(age)))
    except Exception as err:
        msg = "Cannot fetch full dump age: %s" % str(err)

    app = create_app()
    with app.app_context():
        if not current_app.config['TESTING'] and msg:
            send_mail(subject="ListenBrainz outdated dumps!",
                      text=render_template('emails/data_dump_outdated.txt',
                                           msg=msg),
                      recipients=['*****@*****.**'],
                      from_name='ListenBrainz',
                      from_addr='noreply@' +
                      current_app.config['MAIL_FROM_DOMAIN'])
Exemplo n.º 14
0
def notify_artist_relation_import(data):
    """ Send an email after artist relation has been sucessfully imported into the cluster.
    """
    if current_app.config['TESTING']:
        return

    artist_relation_name = data['import_artist_relation']
    import_time = data['import_time']
    time_taken_to_import = data['time_taken_to_import']

    send_mail(
        subject='Artist relation has been imported into the Spark cluster',
        text=render_template('emails/artist_relation_import_notification.txt',
                             artist_relation_name=artist_relation_name, import_time=import_time,
                             time_taken_to_import=time_taken_to_import),
        recipients=['*****@*****.**'],
        from_name='ListenBrainz',
        from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN'],
    )
Exemplo n.º 15
0
def handle_dump_imported(data):
    """ Process the response that the cluster sends after importing a new dump

    We don't really need to _do_ anything, just send an email over if there was an error.
    """
    if current_app.config['TESTING']:
        return

    errors = data['errors']
    import_completion_time = data['time']

    if errors:
        send_mail(
            subject='Spark Cluster Dump import failures!',
            text=render_template('emails/dump_import_failure.txt', errors=errors, time=import_completion_time),
            recipients=['*****@*****.**'],
            from_name='ListenBrainz',
            from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN'],
        )
Exemplo n.º 16
0
def notify_cf_recording_recommendations_generation(data):
    """
    Send an email to notify recommendations have been generated and are being written into db.
    """
    if current_app.config['TESTING']:
        return

    active_user_count = data['active_user_count']
    total_time = data['total_time']
    top_artist_user_count = data['top_artist_user_count']
    similar_artist_user_count = data['similar_artist_user_count']
    send_mail(
        subject='Recommendations have been generated and pushed to the queue.',
        text=render_template('emails/cf_recording_recommendation_notification.txt',
                             active_user_count=active_user_count, total_time=total_time,
                             top_artist_user_count=top_artist_user_count, similar_artist_user_count=similar_artist_user_count),
        recipients=['*****@*****.**'],
        from_name='ListenBrainz',
        from_addr='noreply@'+current_app.config['MAIL_FROM_DOMAIN'],
    )
Exemplo n.º 17
0
def notify_error(musicbrainz_id: str, error: str):
    """ Notifies specified user via email about error during Spotify import.

    Args:
        musicbrainz_id: the MusicBrainz ID of the user
        error: a description of the error encountered.
    """
    user_email = db_user.get_by_mb_id(musicbrainz_id,
                                      fetch_email=True)["email"]
    if not user_email:
        return

    spotify_url = current_app.config[
        'SERVER_ROOT_URL'] + '/profile/music-services/details/'
    text = render_template('emails/spotify_import_error.txt',
                           error=error,
                           link=spotify_url)
    send_mail(
        subject='ListenBrainz Spotify Importer Error',
        text=text,
        recipients=[user_email],
        from_name='ListenBrainz',
        from_addr='noreply@' + current_app.config['MAIL_FROM_DOMAIN'],
    )