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']))
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']))
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']))
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"})
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)
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']))
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']))
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']))
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!"})
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)
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)
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')
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')