Ejemplo n.º 1
0
    def test_dump_recording_feedback(self):

        # create a user
        with self.app.app_context():
            one_id = db_user.create(1, 'test_user')
            user_count = db_user.get_user_count()
            self.assertEqual(user_count, 1)

            # insert a feedback record
            feedback = Feedback(
                user_id=one_id,
                recording_msid="d23f4719-9212-49f0-ad08-ddbfbfc50d6f",
                score=1)
            db_feedback.insert(feedback)

            # do a db dump and reset the db
            private_dump, private_ts_dump, public_dump, public_ts_dump = db_dump.dump_postgres_db(
                self.tempdir)
            self.reset_db()
            user_count = db_user.get_user_count()
            self.assertEqual(user_count, 0)
            self.assertEqual(
                db_feedback.get_feedback_count_for_user(user_id=one_id), 0)

            # import the dump and check the records are inserted
            db_dump.import_postgres_dump(private_dump, None, public_dump, None)
            user_count = db_user.get_user_count()
            self.assertEqual(user_count, 1)

            dumped_feedback = db_feedback.get_feedback_for_user(user_id=one_id,
                                                                limit=1,
                                                                offset=0)
            self.assertEqual(len(dumped_feedback), 1)
            self.assertEqual(dumped_feedback[0].user_id, feedback.user_id)
            self.assertEqual(dumped_feedback[0].recording_msid,
                             feedback.recording_msid)
            self.assertEqual(dumped_feedback[0].score, feedback.score)

            # reset again, and use more threads to import
            self.reset_db()
            user_count = db_user.get_user_count()
            self.assertEqual(user_count, 0)
            dumped_feedback = []

            db_dump.import_postgres_dump(private_dump,
                                         None,
                                         public_dump,
                                         None,
                                         threads=2)
            user_count = db_user.get_user_count()
            self.assertEqual(user_count, 1)

            dumped_feedback = db_feedback.get_feedback_for_user(user_id=one_id,
                                                                limit=1,
                                                                offset=0)
            self.assertEqual(len(dumped_feedback), 1)
            self.assertEqual(dumped_feedback[0].user_id, feedback.user_id)
            self.assertEqual(dumped_feedback[0].recording_msid,
                             feedback.recording_msid)
            self.assertEqual(dumped_feedback[0].score, feedback.score)
Ejemplo n.º 2
0
    def test_update_score_when_feedback_already_exits(self):
        update_fb = self.sample_feedback[0]

        count = self.insert_test_data(self.user["id"])
        result = db_feedback.get_feedback_for_user(user_id=self.user["id"],
                                                   limit=25,
                                                   offset=0)
        self.assertEqual(len(result), count)

        self.assertEqual(result[1].recording_msid, update_fb["recording_msid"])
        self.assertEqual(result[1].score, 1)

        update_fb["score"] = -1  # change the score to -1

        # update a record by inserting a record with updated score value
        db_feedback.insert(
            Feedback(user_id=self.user["id"],
                     recording_msid=update_fb["recording_msid"],
                     score=update_fb["score"]))

        result = db_feedback.get_feedback_for_user(user_id=self.user["id"],
                                                   limit=25,
                                                   offset=0)
        self.assertEqual(len(result), count)

        self.assertEqual(result[0].recording_msid, update_fb["recording_msid"])
        self.assertEqual(result[0].score, -1)
Ejemplo n.º 3
0
    def insert_test_data(self, user_id, neg_score=False):
        """ Insert test data into the database """

        for fb in self.sample_feedback:
            db_feedback.insert(
                Feedback(user_id=user_id,
                         recording_msid=fb["recording_msid"],
                         score=fb["score"]))

        return len(self.sample_feedback)
Ejemplo n.º 4
0
    def test_create_feedback(self, mock_notify):

        self.user = db_user.get_or_create(1, "ernie")
        self.user2 = db_user.get_or_create(2, "bert")
        sample_feedback = [{
            "user_id": self.user['id'],
            "recording_msid": "d23f4719-9212-49f0-ad08-ddbfbfc50d6f",
            "score": 1
        }, {
            "user_id": self.user2['id'],
            "recording_msid": "222eb00d-9ead-42de-aec9-8f8c1509413d",
            "score": -1
        }]
        for fb in sample_feedback:
            db_feedback.insert(
                Feedback(user_id=fb["user_id"],
                         recording_msid=fb["recording_msid"],
                         score=fb["score"]))

        rec_feedback = [{
            "recording_mbid": "d23f4719-9212-49f0-ad08-ddbfbfc50d6f",
            "rating": 'love',
            'user_id': self.user['id']
        }, {
            "recording_mbid": "222eb00d-9ead-42de-aec9-8f8c1509413d",
            "rating": 'bad_recommendation',
            "user_id": self.user['id']
        }, {
            "recording_mbid": "922eb00d-9ead-42de-aec9-8f8c1509413d",
            "rating": 'hate',
            "user_id": self.user2['id']
        }]
        for fb in rec_feedback:
            db_rec_feedback.insert(
                RecommendationFeedbackSubmit(
                    user_id=fb['user_id'],
                    recording_mbid=fb["recording_mbid"],
                    rating=fb["rating"]))

        # create a feedback dump
        self.runner.invoke(dump_manager.create_feedback,
                           ['--location', self.tempdir])
        self.assertEqual(len(os.listdir(self.tempdir)), 1)
        dump_name = os.listdir(self.tempdir)[0]
        mock_notify.assert_called_with(dump_name, 'feedback')

        # make sure that the dump contains a feedback dump
        archive_count = 0
        for file_name in os.listdir(os.path.join(self.tempdir, dump_name)):
            if file_name.endswith('.tar.xz'):
                archive_count += 1
        self.assertEqual(archive_count, 1)
    def insert_test_data(self, user_id):
        sample_feedback = [{
            "recording_msid": "d23f4719-9212-49f0-ad08-ddbfbfc50d6f",
            "score": 1
        }, {
            "recording_msid": "222eb00d-9ead-42de-aec9-8f8c1509413d",
            "score": -1
        }]
        for fb in sample_feedback:
            db_feedback.insert(
                Feedback(user_id=user_id,
                         recording_msid=fb["recording_msid"],
                         score=fb["score"]))

        return sample_feedback
def recording_feedback():
    """
    Submit recording feedback (love/hate) to the server. A user token (found on  https://listenbrainz.org/profile/ )
    must be provided in the Authorization header! Each request should contain only one feedback in the payload.

    For complete details on the format of the JSON to be POSTed to this endpoint, see :ref:`feedback-json-doc`.

    :reqheader Authorization: Token <user token>
    :statuscode 200: feedback accepted.
    :statuscode 400: invalid JSON sent, see error message for details.
    :statuscode 401: invalid authorization. See error message for details.
    :resheader Content-Type: *application/json*
    """
    user = _validate_auth_header()

    data = request.json

    if 'recording_msid' not in data or 'score' not in data:
        log_raise_400(
            "JSON document must contain recording_msid and "
            "score top level keys", data)

    if 'recording_msid' in data and 'score' in data and len(data) > 2:
        log_raise_400(
            "JSON document may only contain recording_msid and "
            "score top level keys", data)

    try:
        feedback = Feedback(user_id=user["id"],
                            recording_msid=data["recording_msid"],
                            score=data["score"])
    except ValidationError as e:
        # Validation errors from the Pydantic model are multi-line. While passing it as a response the new lines
        # are displayed as \n. str.replace() to tidy up the error message so that it becomes a good one line error message.
        log_raise_400(
            "Invalid JSON document submitted: %s" %
            str(e).replace("\n ", ":").replace("\n", " "), data)
    try:
        if feedback.score == 0:
            db_feedback.delete(feedback)
        else:
            db_feedback.insert(feedback)
    except Exception as e:
        current_app.logger.error(
            "Error while inserting recording feedback: {}".format(e))
        raise APIInternalServerError("Something went wrong. Please try again.")

    return jsonify({'status': 'ok'})
    def insert_test_data_with_metadata(self, user_id, neg_score=False):
        """ Insert test data with metadata into the database """

        with msb_db.engine.connect() as connection:
            msid = get_id_from_meta_hash(connection, self.sample_recording)
            if msid is None:
                msid = submit_recording(connection, self.sample_recording)
            msid = str(msid)

            artists = load_recordings_from_msids(connection, [msid])
            self.saved_artist_msid = artists[0]["ids"]["artist_msid"]

        self.sample_feedback_with_metadata[0]["recording_msid"] = msid

        query = """INSERT INTO mbid_mapping_metadata
                               (recording_mbid, release_mbid, release_name, artist_credit_id,
                                artist_mbids, artist_credit_name, recording_name)
                        VALUES ('076255b4-1575-11ec-ac84-135bf6a670e3',
                                '1fd178b4-1575-11ec-b98a-d72392cd8c97',
                                'release_name',
                                65,
                                '{6a221fda-2200-11ec-ac7d-dfa16a57158f}'::UUID[],
                                'artist name', 'recording name')"""

        with ts.engine.connect() as connection:
            connection.execute(sqlalchemy.text(query))

        query = """INSERT INTO mbid_mapping
                               (recording_msid, recording_mbid, match_type, last_updated)
                        VALUES (:msid, :mbid, :match_type, now())"""

        with ts.engine.connect() as connection:
            connection.execute(
                sqlalchemy.text(query), {
                    "msid": msid,
                    "mbid": "076255b4-1575-11ec-ac84-135bf6a670e3",
                    "match_type": "exact_match"
                })

        for fb in self.sample_feedback_with_metadata:
            db_feedback.insert(
                Feedback(user_id=user_id,
                         recording_msid=fb["recording_msid"],
                         score=fb["score"]))

        return len(self.sample_feedback_with_metadata)
Ejemplo n.º 8
0
def recording_feedback():
    """
    Submit recording feedback (love/hate) to the server. A user token (found on  https://listenbrainz.org/profile/ )
    must be provided in the Authorization header! Each request should contain only one feedback in the payload.

    For complete details on the format of the JSON to be POSTed to this endpoint, see :ref:`feedback-json-doc`.

    :reqheader Authorization: Token <user token>
    :statuscode 200: feedback accepted.
    :statuscode 400: invalid JSON sent, see error message for details.
    :statuscode 401: invalid authorization. See error message for details.
    :resheader Content-Type: *application/json*
    """
    user = validate_auth_header()

    data = request.json

    if ('recording_msid' not in data
            and 'recording_mbid' not in data) or 'score' not in data:
        log_raise_400(
            "JSON document must contain either recording_msid or recording_mbid, and "
            "score top level keys", data)

    if set(data) - {"recording_msid", "recording_mbid", "score"}:
        log_raise_400(
            "JSON document may only contain recording_msid, recording_mbid and "
            "score top level keys", data)

    try:
        feedback = Feedback(user_id=user["id"],
                            recording_msid=data.get("recording_msid", None),
                            recording_mbid=data.get("recording_mbid", None),
                            score=data["score"])
    except ValidationError as e:
        # Validation errors from the Pydantic model are multi-line. While passing it as a response the new lines
        # are displayed as \n. str.replace() to tidy up the error message so that it becomes a good one line error message.
        log_raise_400(
            "Invalid JSON document submitted: %s" %
            str(e).replace("\n ", ":").replace("\n", " "), data)

    if feedback.score == FEEDBACK_DEFAULT_SCORE:
        db_feedback.delete(feedback)
    else:
        db_feedback.insert(feedback)

    return jsonify({'status': 'ok'})
Ejemplo n.º 9
0
    def insert_test_data_with_metadata(self, user_id, neg_score=False):
        """ Insert test data with metadata into the database """

        with msb_db.engine.connect() as connection:
            msid = submit_recording(connection, self.sample_recording)
            artists = load_recordings_from_msids(connection, [msid])
            self.saved_artist_msid = artists[0]["ids"]["artist_msid"]

        self.sample_feedback_with_metadata[0]["recording_msid"] = msid

        query = """INSERT INTO listen_mbid_mapping
                               (id, recording_mbid, release_mbid, artist_credit_id, artist_mbids,
                                artist_credit_name, recording_name, match_type)
                        VALUES (1,
                                '076255b4-1575-11ec-ac84-135bf6a670e3',
                                '1fd178b4-1575-11ec-b98a-d72392cd8c97',
                                65, 
                                '{6a221fda-2200-11ec-ac7d-dfa16a57158f}'::UUID[],
                                'artist name', 'recording name', 'exact_match')"""

        with ts.engine.connect() as connection:
            connection.execute(sqlalchemy.text(query))

        query = """INSERT INTO listen_join_listen_mbid_mapping
                               (recording_msid, listen_mbid_mapping)
                        VALUES ('%s', 1)""" % msid

        with ts.engine.connect() as connection:
            connection.execute(sqlalchemy.text(query))

        for fb in self.sample_feedback_with_metadata:
            db_feedback.insert(
                Feedback(user_id=user_id,
                         recording_msid=fb["recording_msid"],
                         score=fb["score"]))

        return len(self.sample_feedback_with_metadata)