add method and route to fetch similar artists from lastfm

This commit is contained in:
geoffrey45 2023-03-12 19:28:41 +03:00
parent e3ec9db989
commit fed62bf7f4
6 changed files with 62 additions and 45 deletions

View File

@ -1,6 +1,7 @@
""" """
Contains all the artist(s) routes. Contains all the artist(s) routes.
""" """
import random
from collections import deque from collections import deque
from flask import Blueprint, request from flask import Blueprint, request
@ -9,6 +10,7 @@ from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
from app.db.store import Store from app.db.store import Store
from app.models import Album, FavType, Track from app.models import Album, FavType, Track
from app.utils.remove_duplicates import remove_duplicates from app.utils.remove_duplicates import remove_duplicates
from app.requests.artists import fetch_similar_artists
api = Blueprint("artist", __name__, url_prefix="/") api = Blueprint("artist", __name__, url_prefix="/")
@ -267,61 +269,36 @@ def get_artist_albums(artisthash: str):
@api.route("/artist/<artisthash>/tracks", methods=["GET"]) @api.route("/artist/<artisthash>/tracks", methods=["GET"])
def get_artist_tracks(artisthash: str): def get_all_artist_tracks(artisthash: str):
""" """
Returns all artists by a given artist. Returns all artists by a given artist.
""" """
tracks = Store.get_tracks_by_artist(artisthash) tracks = Store.get_tracks_by_artist(artisthash)
return {"tracks": tracks} return {"tracks": tracks}
# artist = Store.get_artist_by_hash(artisthash)
# if artist is None:
# return {"error": "Artist not found"}, 404
# return {"albums": albums[:limit]}
# @artist_bp.route("/artist/<artist>") @api.route("/artist/<artisthash>/similar", methods=["GET"])
# @cache.cached() def get_similar_artists(artisthash: str):
# def get_artist_data(artist: str): """
# """Returns the artist's data, tracks and albums""" Returns similar artists.
# artist = urllib.parse.unquote(artist) """
# artist_obj = instances.artist_instance.get_artists_by_name(artist) limit = request.args.get("limit")
# def get_artist_tracks(): if limit is None:
# songs = instances.tracks_instance.find_songs_by_artist(artist) limit = 6
# return songs limit = int(limit)
# artist_songs = get_artist_tracks() artist = Store.get_artist_by_hash(artisthash)
# songs = utils.remove_duplicates(artist_songs)
# def get_artist_albums(): if artist is None:
# artist_albums = [] return {"error": "Artist not found"}, 404
# albums_with_count = []
# albums = instances.tracks_instance.find_songs_by_albumartist(artist) similar_hashes = fetch_similar_artists(artist.name)
similar = Store.get_artists_by_hashes(similar_hashes)
# for song in albums: if len(similar) > limit:
# if song["album"] not in artist_albums: similar = random.sample(similar, limit)
# artist_albums.append(song["album"])
# for album in artist_albums: return {"similar": similar[:limit]}
# count = 0
# length = 0
# for song in artist_songs:
# if song["album"] == album:
# count = count + 1
# length = length + song["length"]
# album_ = {"title": album, "count": count, "length": length}
# albums_with_count.append(album_)
# return albums_with_count
# return {
# "artist": artist_obj,
# "songs": songs,
# "albums": get_artist_albums()
# }

View File

@ -440,12 +440,21 @@ class Store:
@classmethod @classmethod
def get_artist_by_hash(cls, artisthash: str) -> Artist: def get_artist_by_hash(cls, artisthash: str) -> Artist:
""" """
Returns an artist by its hash. Returns an artist by its hash.P
""" """
artists = sorted(cls.artists, key=lambda x: x.artisthash) artists = sorted(cls.artists, key=lambda x: x.artisthash)
artist = UseBisection(artists, "artisthash", [artisthash])()[0] artist = UseBisection(artists, "artisthash", [artisthash])()[0]
return artist return artist
@classmethod
def get_artists_by_hashes(cls, artisthashes: list[str]) -> list[Artist]:
"""
Returns artists by their hashes.
"""
artists = sorted(cls.artists, key=lambda x: x.artisthash)
artists = UseBisection(artists, "artisthash", artisthashes)()
return [a for a in artists if a is not None]
@classmethod @classmethod
def artist_exists(cls, artisthash: str) -> bool: def artist_exists(cls, artisthash: str) -> bool:
""" """

3
app/requests/__init__.py Normal file
View File

@ -0,0 +1,3 @@
"""
All network requests are defined here.
"""

24
app/requests/artists.py Normal file
View File

@ -0,0 +1,24 @@
"""
Requests related to artists
"""
import requests
from app import settings
from app.utils.hashing import create_hash
def fetch_similar_artists(name: str):
"""
Fetches similar artists from Last.fm
"""
url = f"https://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist={name}&api_key=" \
f"{settings.Keys.LASTFM_API_KEY}&format=json&limit=100"
response = requests.get(url, timeout=10)
response.raise_for_status()
data = response.json()
artists = data["similarartists"]["artist"]
for artist in artists:
yield create_hash(artist["name"])

View File

@ -125,3 +125,6 @@ class TCOLOR:
# credits: https://stackoverflow.com/a/287944 # credits: https://stackoverflow.com/a/287944
class Keys:
# get last fm api key from os environment
LASTFM_API_KEY = os.environ.get("LASTFM_API_KEY")

View File

@ -26,3 +26,4 @@ def get_ip():
soc.close() soc.close()
return ip_address return ip_address