예제 #1
0
 def test_is_following_user(self):
     self.assertFalse(
         db_user_relationship.is_following_user(self.main_user['id'],
                                                self.followed_user_1['id']))
     db_user_relationship.insert(self.main_user['id'],
                                 self.followed_user_1['id'], 'follow')
     self.assertTrue(
         db_user_relationship.is_following_user(self.main_user['id'],
                                                self.followed_user_1['id']))
예제 #2
0
    def test_unfollow_user(self):
        # first, follow the user
        r = self.client.post(self.follow_user_url, headers=self.follow_user_headers)
        self.assert200(r)
        self.assertTrue(db_user_relationship.is_following_user(self.user.id, self.followed_user['id']))

        # now, unfollow and check the db
        r = self.client.post(url_for("social_api_v1.unfollow_user", user_name=self.followed_user["musicbrainz_id"]),
                             headers=self.follow_user_headers)
        self.assert200(r)
        self.assertFalse(db_user_relationship.is_following_user(self.user.id, self.followed_user['id']))
예제 #3
0
 def test_follow_user(self):
     r = self.client.post(self.follow_user_url,
                          headers=self.follow_user_headers)
     self.assert200(r)
     self.assertTrue(
         db_user_relationship.is_following_user(self.user.id,
                                                self.followed_user['id']))
예제 #4
0
def follow_user(user_name: str):
    """
    Follow the user ``user_name``. A user token (found on  https://listenbrainz.org/profile/ ) must
    be provided in the Authorization header!

    :reqheader Authorization: Token <user token>
    :reqheader Content-Type: *application/json*
    :statuscode 200: Successfully followed the user ``user_name``.
    :statuscode 400:
                    - Already following the user ``user_name``.
                    - Trying to follow yourself.
    :statuscode 401: invalid authorization. See error message for details.
    :resheader Content-Type: *application/json*
    """
    current_user = validate_auth_header()
    user = db_user.get_by_mb_id(user_name)

    if not user:
        raise APINotFound("User %s not found" % user_name)

    if user["musicbrainz_id"] == current_user["musicbrainz_id"]:
        raise APIBadRequest("Whoops, cannot follow yourself.")

    if db_user_relationship.is_following_user(current_user["id"], user["id"]):
        raise APIBadRequest("%s is already following user %s" % (current_user["musicbrainz_id"], user["musicbrainz_id"]))

    try:
        db_user_relationship.insert(current_user["id"], user["id"], "follow")
    except Exception as e:
        current_app.logger.error("Error while trying to insert a relationship: %s", str(e))
        raise APIInternalServerError("Something went wrong, please try again later")

    return jsonify({"status": "ok"})
예제 #5
0
    def test_follow_user_twice_leads_to_error(self):
        r = self.client.post(self.follow_user_url, headers=self.follow_user_headers)
        self.assert200(r)
        self.assertTrue(db_user_relationship.is_following_user(self.user.id, self.followed_user['id']))

        # now, try to follow again, this time expecting a 400
        r = self.client.post(self.follow_user_url, headers=self.follow_user_headers)
        self.assert400(r)
예제 #6
0
 def test_unfollow_not_following_user(self):
     r = self.client.post(url_for(
         "social_api_v1.unfollow_user",
         user_name=self.followed_user["musicbrainz_id"]),
                          headers=self.follow_user_headers)
     self.assert200(r)
     self.assertFalse(
         db_user_relationship.is_following_user(self.user.id,
                                                self.followed_user['id']))
예제 #7
0
    def test_unfollow_user(self):
        followed_user = db_user.get_or_create(3, 'followed_user')

        self.temporary_login(self.user.login_id)

        # first, follow the user
        r = self.client.post('/user/followed_user/follow')
        self.assert200(r)
        self.assertTrue(
            db_user_relationship.is_following_user(self.user.id,
                                                   followed_user['id']))

        # now, unfollow and check the db
        r = self.client.post('/user/followed_user/unfollow')
        self.assert200(r)
        self.assertFalse(
            db_user_relationship.is_following_user(self.user.id,
                                                   followed_user['id']))
예제 #8
0
    def test_follow_user(self):
        followed_user = db_user.get_or_create(3, 'followed_user')

        self.temporary_login(self.user.login_id)
        r = self.client.post('/user/followed_user/follow')
        self.assert200(r)
        self.assertTrue(
            db_user_relationship.is_following_user(self.user.id,
                                                   followed_user['id']))
예제 #9
0
def unfollow_user(user_name: str):
    user = _get_user(user_name)
    if not db_user_relationship.is_following_user(current_user.id, user.id):
        raise APIBadRequest(f"{current_user.musicbrainz_id} is not following user {user.musicbrainz_id}")
    try:
        db_user_relationship.delete(current_user.id, user.id, 'follow')
    except Exception:
        current_app.logger.critical("Error while trying to delete a relationship", exc_info=True)
        raise APIInternalServerError("Something went wrong, please try again later")

    return jsonify({"status": 200, "message": "Success!"})
예제 #10
0
def logged_in_user_follows_user(user):
    """ Check if user is being followed by the current user.
    Args:
        user : User object
    Raises:
        NotFound if user isn't present in the database
    """

    if current_user.is_authenticated:
        return db_user_relationship.is_following_user(current_user.id, user.id)
    return None
    def test_get_pins_for_user_following(self):
        # user follows followed_user_1
        db_user_relationship.insert(self.user["id"],
                                    self.followed_user_1["id"], "follow")
        self.assertTrue(
            db_user_relationship.is_following_user(self.user["id"],
                                                   self.followed_user_1["id"]))

        # test that followed_pins contains followed_user_1's pinned recording
        self.pin_single_sample(self.followed_user_1["id"], 0)
        followed_pins = db_pinned_rec.get_pins_for_user_following(user_id=1,
                                                                  count=50,
                                                                  offset=0)
        self.assertEqual(len(followed_pins), 1)
        self.assertEqual(followed_pins[0].user_name, "followed_user_1")

        # test that pins from users that the user is not following are not included
        self.pin_single_sample(self.followed_user_2["id"], 0)
        self.assertEqual(len(followed_pins), 1)

        # test that followed_user_2's pin is included after user follows
        db_user_relationship.insert(self.user["id"],
                                    self.followed_user_2["id"], "follow")
        followed_pins = db_pinned_rec.get_pins_for_user_following(user_id=1,
                                                                  count=50,
                                                                  offset=0)
        self.assertEqual(len(followed_pins), 2)
        self.assertEqual(followed_pins[0].user_name, "followed_user_2")

        # test that list is returned in descending order of creation date
        self.assertGreater(followed_pins[0].created, followed_pins[1].created)
        self.assertEqual(followed_pins[1].user_name, "followed_user_1")

        # test the limit argument
        limit = 1
        limited_following_pins = db_pinned_rec.get_pins_for_user_following(
            user_id=self.user["id"], count=limit, offset=0)
        self.assertEqual(len(limited_following_pins), limit)

        limit = 999
        limited_following_pins = db_pinned_rec.get_pins_for_user_following(
            user_id=self.user["id"], count=limit, offset=0)
        self.assertEqual(len(limited_following_pins), 2)

        # test the offset argument
        offset = 1
        offset_following_pins = db_pinned_rec.get_pins_for_user_following(
            user_id=self.user["id"], count=50, offset=offset)
        self.assertEqual(len(offset_following_pins), 2 - offset)

        offset = 999
        offset_following_pins = db_pinned_rec.get_pin_history_for_user(
            user_id=self.user["id"], count=50, offset=offset)
        self.assertFalse(offset_following_pins)
예제 #12
0
    def test_follow_user_twice_leads_to_error(self):
        followed_user = db_user.get_or_create(3, 'followed_user')

        self.temporary_login(self.user.login_id)
        r = self.client.post('/user/followed_user/follow')
        self.assert200(r)
        self.assertTrue(
            db_user_relationship.is_following_user(self.user.id,
                                                   followed_user['id']))

        # now, try to follow again, this time expecting a 400
        r = self.client.post('/user/followed_user/follow')
        self.assert400(r)
예제 #13
0
def profile(user_name):
    # Which database to use to showing user listens.
    db_conn = webserver.timescale_connection._ts
    # Which database to use to show playing_now stream.
    playing_now_conn = webserver.redis_connection._redis

    user = _get_user(user_name)
    # User name used to get user may not have the same case as original user name.
    user_name = user.musicbrainz_id

    # Getting data for current page
    max_ts = request.args.get("max_ts")
    if max_ts is not None:
        try:
            max_ts = int(max_ts)
        except ValueError:
            raise BadRequest("Incorrect timestamp argument max_ts: %s" % request.args.get("max_ts"))

    min_ts = request.args.get("min_ts")
    if min_ts is not None:
        try:
            min_ts = int(min_ts)
        except ValueError:
            raise BadRequest("Incorrect timestamp argument min_ts: %s" % request.args.get("min_ts"))

    # Send min and max listen times to allow React component to hide prev/next buttons accordingly
    (min_ts_per_user, max_ts_per_user) = db_conn.get_timestamps_for_user(user_name)

    if max_ts is None and min_ts is None:
        if max_ts_per_user:
            max_ts = max_ts_per_user + 1
        else:
            max_ts = int(time.time())

    listens = []
    if min_ts_per_user != max_ts_per_user:
        args = {}
        if max_ts:
            args['to_ts'] = max_ts
        else:
            args['from_ts'] = min_ts
        for listen in db_conn.fetch_listens(user_name, limit=LISTENS_PER_PAGE, **args):
            listens.append({
                "track_metadata": listen.data,
                "listened_at": listen.ts_since_epoch,
                "listened_at_iso": listen.timestamp.isoformat() + "Z",
            })

    # If there are no previous listens then display now_playing
    if not listens or listens[0]['listened_at'] >= max_ts_per_user:
        playing_now = playing_now_conn.get_playing_now(user.id)
        if playing_now:
            listen = {
                "track_metadata": playing_now.data,
                "playing_now": "true",
            }
            listens.insert(0, listen)

    user_stats = db_stats.get_user_artists(user.id, 'all_time')
    try:
        artist_count = user_stats.all_time.count
    except (AttributeError, ValidationError):
        artist_count = None

    spotify_data = {}
    current_user_data = {}
    logged_in_user_follows_user = None
    if current_user.is_authenticated:
        spotify_data = spotify.get_user_dict(current_user.id)
        current_user_data = {
            "id": current_user.id,
            "name": current_user.musicbrainz_id,
            "auth_token": current_user.auth_token,
        }
        logged_in_user_follows_user = db_user_relationship.is_following_user(current_user.id, user.id)

    props = {
        "user": {
            "id": user.id,
            "name": user.musicbrainz_id,
        },
        "current_user": current_user_data,
        "listens": listens,
        "latest_listen_ts": max_ts_per_user,
        "oldest_listen_ts": min_ts_per_user,
        "latest_spotify_uri": _get_spotify_uri_for_listens(listens),
        "artist_count": format(artist_count, ",d") if artist_count else None,
        "profile_url": url_for('user.profile', user_name=user_name),
        "mode": "listens",
        "spotify": spotify_data,
        "web_sockets_server_url": current_app.config['WEBSOCKETS_SERVER_URL'],
        "api_url": current_app.config['API_URL'],
        "logged_in_user_follows_user": logged_in_user_follows_user,
    }

    return render_template("user/profile.html",
                           props=ujson.dumps(props),
                           mode='listens',
                           user=user,
                           active_section='listens')
예제 #14
0
def profile(user_name):
    # Which database to use to showing user listens.
    db_conn = webserver.timescale_connection._ts
    # Which database to use to show playing_now stream.
    playing_now_conn = webserver.redis_connection._redis

    user = _get_user(user_name)
    # User name used to get user may not have the same case as original user name.
    user_name = user.musicbrainz_id

    # Getting data for current page
    max_ts = request.args.get("max_ts")
    if max_ts is not None:
        try:
            max_ts = int(max_ts)
        except ValueError:
            raise BadRequest("Incorrect timestamp argument max_ts: %s" %
                             request.args.get("max_ts"))

    min_ts = request.args.get("min_ts")
    if min_ts is not None:
        try:
            min_ts = int(min_ts)
        except ValueError:
            raise BadRequest("Incorrect timestamp argument min_ts: %s" %
                             request.args.get("min_ts"))

    args = {}
    if max_ts:
        args['to_ts'] = max_ts
    else:
        args['from_ts'] = min_ts
    data, min_ts_per_user, max_ts_per_user = db_conn.fetch_listens(
        user_name, limit=LISTENS_PER_PAGE, **args)

    listens = []
    for listen in data:
        listens.append(listen.to_api())

    # If there are no previous listens then display now_playing
    if not listens or listens[0]['listened_at'] >= max_ts_per_user:
        playing_now = playing_now_conn.get_playing_now(user.id)
        if playing_now:
            listen = {
                "track_metadata": playing_now.data,
                "playing_now": "true",
            }
            listens.insert(0, listen)

    user_stats = db_stats.get_user_stats(user.id, 'all_time', 'artists')

    logged_in_user_follows_user = None
    already_reported_user = False
    if current_user.is_authenticated:
        logged_in_user_follows_user = db_user_relationship.is_following_user(
            current_user.id, user.id)
        already_reported_user = db_user.is_user_reported(
            current_user.id, user.id)

    pin = get_current_pin_for_user(user_id=user.id)
    if pin:
        pin = dict(fetch_track_metadata_for_pins([pin])[0])

    props = {
        "user": {
            "id": user.id,
            "name": user.musicbrainz_id,
        },
        "listens": listens,
        "latest_listen_ts": max_ts_per_user,
        "oldest_listen_ts": min_ts_per_user,
        "latest_spotify_uri": _get_spotify_uri_for_listens(listens),
        "artist_count": format(user_stats.count, ",d") if user_stats else None,
        "profile_url": url_for('user.profile', user_name=user_name),
        "mode": "listens",
        "userPinnedRecording": pin,
        "web_sockets_server_url": current_app.config['WEBSOCKETS_SERVER_URL'],
        "logged_in_user_follows_user": logged_in_user_follows_user,
        "already_reported_user": already_reported_user,
    }

    return render_template("user/profile.html",
                           props=ujson.dumps(props),
                           mode='listens',
                           user=user,
                           active_section='listens')