diff --git a/server/app/api.py b/server/app/api.py index fa958bbf..6e508cec 100644 --- a/server/app/api.py +++ b/server/app/api.py @@ -1,13 +1,14 @@ import os import urllib +from typing import List from flask import Blueprint, request from app import functions, instances, helpers, cache -bp = Blueprint('api', __name__, url_prefix='') +bp = Blueprint("api", __name__, url_prefix="") home_dir = helpers.home_dir -all_the_f_music = helpers.getAllSongs() +all_the_f_music = helpers.get_all_songs() def initialize() -> None: @@ -15,45 +16,58 @@ def initialize() -> None: Runs all the necessary setup functions. """ helpers.create_config_dir() - # helpers.check_for_new_songs() + helpers.check_for_new_songs() initialize() -@bp.route('/') -def adutsfsd(): +@bp.route("/") +def say_hi(): + """Returns some text for the default route""" return "^ _ ^" -@bp.route('/search') +def get_tracks(query: str) -> List: + """ + Gets all songs with a given title. + """ + return [track for track in all_the_f_music if query.lower() in track.title.lower()] + + +def get_search_albums(query: str) -> List: + """ + Gets all songs with a given album. + """ + return [track for track in all_the_f_music if query.lower() in track.album.lower()] + + +def get_artists(artist: str) -> List: + """ + Gets all songs with a given artist. + """ + return [ + track + for track in all_the_f_music + if artist.lower() in str(track.artists).lower() + ] + + +@bp.route("/search") def search_by_title(): - if not request.args.get('q'): - query:str = "mexican girl" - else: - query:str = str(request.args.get('q')) - - albums = [] - artists = [] - tracks = [] + """ + Returns a list of songs, albums and artists that match the search query. + """ + query = request.args.get("q") or "Mexican girl" + albums = get_search_albums(query) albums_dicts = [] artists_dicts = [] - for track in all_the_f_music: - if query.lower() in track.title.lower(): - tracks.append(track) - - if query.lower() in track.album.lower(): - albums.append(track) - - if query.lower() in str(track.artists).lower(): - artists.append(track) - for song in albums: album_obj = { "name": song.album, - "artist": song.album_artist, + "artist": song.albumartist, } if album_obj not in albums_dicts: @@ -61,61 +75,52 @@ def search_by_title(): for album in albums_dicts: for track in albums: - if album['name'] == track.album: - album['image'] = track.image + if album["name"] == track.album: + album["image"] = track.image - for song in artists: + for song in get_artists(query): for artist in song.artists: if query.lower() in artist.lower(): artist_obj = { "name": artist, - "image": "http://0.0.0.0:8900/images/artists/" + artist.replace("/", "::") + ".webp" + "image": "http://0.0.0.0:8900/images/artists/" + + artist.replace("/", "::") + + ".webp", } if artist_obj not in artists_dicts: artists_dicts.append(artist_obj) - tracks = helpers.remove_duplicates(tracks) + tracks = helpers.remove_duplicates(get_tracks(query)) - if len(tracks) > 5: - more_tracks = True - else: - more_tracks = False - - if len(artists_dicts) > 6: - more_artists = True - else: - more_artists = False - - if len(albums_dicts) > 6: - more_albums = True - else: - more_albums = False - - return {'data': [ - {'tracks': tracks[:5], 'more': more_tracks}, - {'albums': albums_dicts[:6], 'more': more_albums}, - {'artists': artists_dicts[:6], 'more': more_artists} - ]} + return { + "data": [ + {"tracks": tracks[:5], "more": len(tracks) > 5}, + {"albums": albums_dicts[:6], "more": len(albums_dicts) > 6}, + {"artists": artists_dicts[:6], "more": len(artists_dicts) > 6}, + ] + } -@bp.route('/populate') -def x(): +@bp.route("/populate") +def find_tracks(): + """call the populate function""" functions.populate() return "🎸" @bp.route("/album///artists") @cache.cached() -def get_album_artists(album, artist): - album = album.replace('|', '/') - artist = artist.replace('|', '/') +def get_albumartists(album, artist): + """Returns a list of artists featured in a given album.""" + album = album.replace("|", "/") + artist = artist.replace("|", "/") tracks = [] for track in all_the_f_music: - if track.album == album and track.album_artist == artist: + if track.album == album and track.albumartist == artist: tracks.append(track) artists = [] @@ -129,11 +134,13 @@ def get_album_artists(album, artist): for artist in artists: artist_obj = { "name": artist, - "image": "http://0.0.0.0:8900/images/artists/" + artist.replace('/', '::') + ".webp" + "image": "http://0.0.0.0:8900/images/artists/" + + artist.replace("/", "::") + + ".webp", } final_artists.append(artist_obj) - return {'artists': final_artists} + return {"artists": final_artists} @bp.route("/populate/images") @@ -144,55 +151,54 @@ def populate_images(): @bp.route("/artist/") @cache.cached() -def getArtistData(artist: str): - print(artist) +def get_artist_data(artist: str): + """Returns the artist's data, tracks and albums""" artist = urllib.parse.unquote(artist) artist_obj = instances.artist_instance.get_artists_by_name(artist) - def getArtistSongs(): + def get_artist_tracks(): songs = instances.songs_instance.find_songs_by_artist(artist) return songs - artist_songs = getArtistSongs() + artist_songs = get_artist_tracks() songs = helpers.remove_duplicates(artist_songs) - def getArtistAlbums(): + def get_artist_albums(): artist_albums = [] albums_with_count = [] - albums = instances.songs_instance.find_songs_by_album_artist(artist) + albums = instances.songs_instance.find_songs_by_albumartist(artist) for song in albums: - if song['album'] not in artist_albums: - artist_albums.append(song['album']) + if song["album"] not in artist_albums: + artist_albums.append(song["album"]) for album in artist_albums: count = 0 length = 0 for song in artist_songs: - if song['album'] == album: + if song["album"] == album: count = count + 1 - length = length + song['length'] + length = length + song["length"] - album_ = { - "title": album, - "count": count, - "length": length - } + album_ = {"title": album, "count": count, "length": length} albums_with_count.append(album_) return albums_with_count - return {'artist': artist_obj, 'songs': songs, 'albums': getArtistAlbums()} + return {"artist": artist_obj, "songs": songs, "albums": get_artist_albums()} @bp.route("/f/") @cache.cached() -def getFolderTree(folder: str): - req_dir = folder.replace('|', '/') +def get_folder_tree(folder: str): + """ + Returns a list of all the folders and tracks in the given folder. + """ + req_dir = folder.replace("|", "/") if folder == "home": req_dir = home_dir @@ -202,9 +208,8 @@ def getFolderTree(folder: str): folders = [] for entry in dir_content: - if entry.is_dir() and not entry.name.startswith('.'): - files_in_dir = helpers.run_fast_scandir( - entry.path, [".flac", ".mp3"])[1] + if entry.is_dir() and not entry.name.startswith("."): + files_in_dir = helpers.run_fast_scandir(entry.path, [".flac", ".mp3"])[1] if len(files_in_dir) != 0: _dir = { @@ -221,35 +226,36 @@ def getFolderTree(folder: str): if track.folder == req_dir: songs.append(track) - return {"files": helpers.remove_duplicates(songs), "folders": sorted(folders, key=lambda i: i['name'])} + return { + "files": helpers.remove_duplicates(songs), + "folders": sorted(folders, key=lambda i: i["name"]), + } - -@bp.route('/albums') -def getAlbums(): +@bp.route("/albums") +def get_albums(): + """returns all the albums""" s = instances.songs_instance.get_all_songs() albums = [] for song in s: - al_obj = { - "name": song['album'], - "artist": song['artists'] - } + al_obj = {"name": song["album"], "artist": song["artists"]} if al_obj not in albums: albums.append(al_obj) - return {'albums': albums} + return {"albums": albums} -@bp.route('/album//<artist>/tracks') +@bp.route("/album/<title>/<artist>/tracks") @cache.cached() -def get_album_tracks(title:str, artist:str): +def get_album_tracks(title: str, artist: str): + """Returns all the tracks in the given album.""" songs = [] for track in all_the_f_music: - if track.album_artist == artist and track.album == title: + if track.albumartist == artist and track.album == title: songs.append(track) songs = helpers.remove_duplicates(songs) @@ -259,16 +265,18 @@ def get_album_tracks(title:str, artist:str): "count": len(songs), "duration": "56 Minutes", "image": songs[0].image, - "artist": songs[0].album_artist, - "artist_image": "http://127.0.0.1:8900/images/artists/" + songs[0].album_artist.replace('/', '::') + ".webp" + "artist": songs[0].albumartist, + "artist_image": "http://127.0.0.1:8900/images/artists/" + + songs[0].albumartist.replace("/", "::") + + ".webp", } - return {'songs': songs, 'info': album_obj} + return {"songs": songs, "info": album_obj} -@bp.route('/album/<title>/<artist>/bio') +@bp.route("/album/<title>/<artist>/bio") @cache.cached() -def drop_db(title, artist): - bio = functions.getAlbumBio(title, artist) - return {'bio': bio}, 200 - +def get_album_bio(title, artist): + """Returns the album bio for the given album.""" + bio = functions.get_album_bio(title, artist) + return {"bio": bio}, 200 diff --git a/server/app/functions.py b/server/app/functions.py index 0b3c8a76..fc26bd59 100644 --- a/server/app/functions.py +++ b/server/app/functions.py @@ -4,17 +4,17 @@ This module contains larger functions for the server import time import os -import requests +from io import BytesIO import random import datetime +import mutagen +import requests from mutagen.flac import MutagenError -from mutagen.mp3 import MP3 from mutagen.id3 import ID3 from mutagen.flac import FLAC from progress.bar import Bar from PIL import Image -from io import BytesIO from app import helpers from app import instances @@ -30,17 +30,30 @@ def populate(): also checks if the album art exists in the image path, if not tries to extract it. """ + start = time.time() print("\nchecking for new tracks") files = helpers.run_fast_scandir(helpers.home_dir, [".flac", ".mp3"])[1] for file in files: - getTags(file) + tags = get_tags(file) - api.all_the_f_music = helpers.getAllSongs() - print("\ncheck done") + if tags is not None: + instances.songs_instance.insert_song(tags) + + api.all_the_f_music = helpers.get_all_songs() + print("\n check done") + end = time.time() + + print( + str(datetime.timedelta(seconds=round(end - start))) + + " elapsed for " + + str(len(files)) + + " files" + ) def populate_images(): + """populates the artists images""" all_songs = instances.songs_instance.get_all_songs() artists = [] @@ -52,7 +65,7 @@ def populate_images(): if artist not in artists: artists.append(artist) - bar = Bar("Processing images", max=len(artists)) + _bar = Bar("Processing images", max=len(artists)) for artist in artists: file_path = ( helpers.app_dir + "/images/artists/" + artist.replace("/", "::") + ".webp" @@ -81,9 +94,17 @@ def populate_images(): time.sleep(5) try_save_image() - bar.next() + _bar.next() - bar.finish() + _bar.finish() + + +def use_defaults() -> str: + """ + Returns a path to a random image in the defaults directory. + """ + path = str(random.randint(0, 10)) + ".webp" + return path def extract_thumb(audio_file_path: str) -> str: @@ -93,13 +114,6 @@ def extract_thumb(audio_file_path: str) -> str: album_art = None - def use_defaults() -> str: - """ - Returns a path to a random image in the defaults directory. - """ - path = str(random.randint(0, 10)) + ".webp" - return path - webp_path = audio_file_path.split("/")[-1] + ".webp" img_path = os.path.join(helpers.app_dir, "images", "thumbnails", webp_path) @@ -138,110 +152,138 @@ def extract_thumb(audio_file_path: str) -> str: return use_defaults() -def getTags(full_path: str) -> dict: +def parse_artist_tag(audio): + """ + Parses the artist tag from an audio file. + """ + try: + artists = audio["artist"][0] + except (KeyError, IndexError): + artists = "Unknown" + + return artists + + +def parse_title_tag(audio, full_path: str): + """ + Parses the title tag from an audio file. + """ + try: + title = audio["title"][0] + except (KeyError, IndexError): + title = full_path.split("/")[-1] + + return title + + +def parse_album_artist_tag(audio): + """ + Parses the album artist tag from an audio file. + """ + try: + albumartist = audio["albumartist"][0] + except (KeyError, IndexError): + albumartist = "Unknown" + + return albumartist + + +def parse_album_tag(audio): + """ + Parses the album tag from an audio file. + """ + try: + album = audio["album"][0] + except (KeyError, IndexError): + album = "Unknown" + + return album + + +def parse_genre_tag(audio): + """ + Parses the genre tag from an audio file. + """ + try: + genre = audio["genre"][0] + except (KeyError, IndexError): + genre = "Unknown" + + return genre + + +def parse_date_tag(audio): + """ + Parses the date tag from an audio file. + """ + try: + date = audio["date"][0] + except (KeyError, IndexError): + date = "Unknown" + + return date + + +def parse_track_number(audio): + """ + Parses the track number from an audio file. + """ + try: + track_number = audio["tracknumber"][0] + except (KeyError, IndexError): + track_number = "Unknown" + + return track_number + + +def parse_disk_number(audio): + """ + Parses the disk number from an audio file. + """ + try: + disk_number = audio["discnumber"][0] + except (KeyError, IndexError): + disk_number = "Unknown" + + return disk_number + + +def get_tags(full_path: str) -> dict: """ Returns a dictionary of tags for a given file. """ - - if full_path.endswith(".flac"): - try: - audio = FLAC(full_path) - except MutagenError: - return - elif full_path.endswith(".mp3"): - try: - audio = MP3(full_path) - except MutagenError: - return - try: - artists = audio["artist"][0] - except KeyError: - try: - artists = audio["TPE1"][0] - except: - artists = "Unknown" - except IndexError: - artists = "Unknown" - - try: - album_artist = audio["albumartist"][0] - except KeyError: - try: - album_artist = audio["TPE2"][0] - except: - album_artist = "Unknown" - except IndexError: - album_artist = "Unknown" - - try: - title = audio["title"][0] - except KeyError: - try: - title = audio["TIT2"][0] - except: - title = full_path.split("/")[-1] - except: - title = full_path.split("/")[-1] - - try: - album = audio["album"][0] - except KeyError: - try: - album = audio["TALB"][0] - except: - album = "Unknown" - except IndexError: - album = "Unknown" - - try: - genre = audio["genre"][0] - except KeyError: - try: - genre = audio["TCON"][0] - except: - genre = "Unknown" - except IndexError: - genre = "Unknown" - - try: - date = audio["date"][0] - except KeyError: - try: - date = audio["TDRC"][0] - except: - date = "Unknown" - except IndexError: - date = "Unknown" - - img_path = extract_thumb(full_path) - - length = str(datetime.timedelta(seconds=round(audio.info.length))) - - if length[:2] == "0:": - length = length.replace("0:", "") + audio = mutagen.File(full_path, easy=True) + except MutagenError: + return None tags = { - "filepath": full_path.replace(helpers.home_dir, ""), - "folder": os.path.dirname(full_path).replace(helpers.home_dir, ""), - "title": title, - "artists": artists, - "album_artist": album_artist, - "album": album, - "genre": genre, - "length": length, + "artists": parse_artist_tag(audio), + "title": parse_title_tag(audio, full_path), + "albumartist": parse_album_artist_tag(audio), + "album": parse_album_tag(audio), + "genre": parse_genre_tag(audio), + "date": parse_date_tag(audio)[:4], + "tracknumber": parse_track_number(audio), + "discnumber": parse_disk_number(audio), + "length": audio.info.length, "bitrate": round(int(audio.info.bitrate) / 1000), - "date": str(date)[:4], - "image": img_path, + "filepath": full_path.replace(helpers.home_dir, ""), + "image": extract_thumb(full_path), + "folder": os.path.dirname(full_path).replace(helpers.home_dir, ""), } - instances.songs_instance.insert_song(tags) + print(tags['filepath']) + return tags -def getAlbumBio(title: str, album_artist: str): +def get_album_bio(title: str, albumartist: str): + """ + Returns the album bio for a given album. + """ last_fm_url = "http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key={}&artist={}&album={}&format=json".format( - helpers.LAST_FM_API_KEY, album_artist, title + helpers.LAST_FM_API_KEY, albumartist, title ) try: @@ -262,11 +304,14 @@ def getAlbumBio(title: str, album_artist: str): def create_track_class(tags): + """ + Creates a Track class from a dictionary of tags. + """ return models.Track( tags["_id"]["$oid"], tags["title"], tags["artists"], - tags["album_artist"], + tags["albumartist"], tags["album"], tags["filepath"], tags["folder"], @@ -275,4 +320,6 @@ def create_track_class(tags): tags["genre"], tags["bitrate"], tags["image"], + tags['tracknumber'], + tags['discnumber'], ) diff --git a/server/app/helpers.py b/server/app/helpers.py index 76dec007..e7043a0b 100644 --- a/server/app/helpers.py +++ b/server/app/helpers.py @@ -127,11 +127,11 @@ def create_config_dir() -> None: os.chmod(path, 0o755) -def getAllSongs() -> List: +def get_all_songs() -> List: """ Gets all songs under the ~/ directory. """ - + print("Getting all songs...") tracks = [] for track in instances.songs_instance.get_all_songs(): @@ -140,6 +140,7 @@ def getAllSongs() -> List: try: os.chmod(os.path.join(home_dir, track.filepath), 0o755) except FileNotFoundError: + print("❌") instances.songs_instance.remove_song_by_filepath(track.filepath) tracks.append(track) diff --git a/server/app/models.py b/server/app/models.py index 17002deb..e614cc62 100644 --- a/server/app/models.py +++ b/server/app/models.py @@ -1,10 +1,13 @@ +import json from dataclasses import dataclass import pymongo -import json from bson import ObjectId, json_util def convert_one_to_json(song): + """ + Converts a single mongodb cursor to a json object. + """ json_song = json.dumps(song, default=json_util.default) loaded_song = json.loads(json_song) @@ -12,6 +15,10 @@ def convert_one_to_json(song): def convert_to_json(array): + """ + Converts a list of mongodb cursors to a list of json objects. + """ + songs = [] for song in array: @@ -24,99 +31,161 @@ def convert_to_json(array): class Mongo: + """ + The base class for all mongodb classes. + """ + def __init__(self, database): mongo_uri = pymongo.MongoClient() self.db = mongo_uri[database] class Artists(Mongo): + """ + The artist class for all artist related database operations. + """ + def __init__(self): - super(Artists, self).__init__('ALL_ARTISTS') - self.collection = self.db['THEM_ARTISTS'] + super(Artists, self).__init__("ALL_ARTISTS") + self.collection = self.db["THEM_ARTISTS"] - def insert_artist(self, artist_obj): - self.collection.update_one( - artist_obj, {'$set': artist_obj}, upsert=True) + def insert_artist(self, artist_obj: dict) -> None: + """ + Inserts an artist into the database. + """ + self.collection.update_one(artist_obj, {"$set": artist_obj}, upsert=True) - def get_all_artists(self): + def get_all_artists(self) -> list: + """ + Returns a list of all artists in the database. + """ return self.collection.find() - def get_artist_by_id(self, artist_id): - return self.collection.find_one({'_id': ObjectId(artist_id)}) + def get_artist_by_id(self, artist_id: str) -> dict: + """ + Returns an artist matching the mongo Id. + """ + return self.collection.find_one({"_id": ObjectId(artist_id)}) - def get_artists_by_name(self, query): - return self.collection.find({'name': query}).limit(20) + def get_artists_by_name(self, query: str): + """ + Returns all the artists matching the query. + """ + return self.collection.find({"name": query}).limit(20) class AllSongs(Mongo): + """ + The class for all track-related database operations. + """ + def __init__(self): - super(AllSongs, self).__init__('ALL_SONGS') - self.collection = self.db['ALL_SONGS'] + super(AllSongs, self).__init__("ALL_SONGS") + self.collection = self.db["ALL_SONGS"] # def drop_db(self): # self.collection.drop() - def insert_song(self, song_obj): + def insert_song(self, song_obj: dict) -> None: + """ + Inserts a new track object into the database. + """ self.collection.update_one( - {'filepath': song_obj['filepath']}, {"$set": song_obj}, upsert=True) + {"filepath": song_obj["filepath"]}, {"$set": song_obj}, upsert=True + ) - def get_all_songs(self): + def get_all_songs(self) -> list: + """ + Returns all tracks in the database. + """ return convert_to_json(self.collection.find()) - def get_song_by_id(self, file_id): - song = self.collection.find_one({'_id': ObjectId(file_id)}) + def get_song_by_id(self, file_id: str) -> dict: + """ + Returns a track object by its mongodb id. + """ + song = self.collection.find_one({"_id": ObjectId(file_id)}) return convert_one_to_json(song) - def get_song_by_album(self, name, artist): - song = self.collection.find_one( - {'album': name, 'album_artist': artist}) + def get_song_by_album(self, name: str, artist: str) -> dict: + """ + Returns a single track matching the album in the query params. + """ + song = self.collection.find_one({"album": name, "albumartist": artist}) return convert_one_to_json(song) - def search_songs_by_album(self, query): - songs = self.collection.find( - {'album': {'$regex': query, '$options': 'i'}}) + def search_songs_by_album(self, query: str) -> list: + """ + Returns all the songs matching the albums in the query params (using regex). + """ + songs = self.collection.find({"album": {"$regex": query, "$options": "i"}}) return convert_to_json(songs) - def search_songs_by_artist(self, query): - songs = self.collection.find( - {'artists': {'$regex': query, '$options': 'i'}}) + def search_songs_by_artist(self, query: str) -> list: + """ + Returns all the songs matching the artists in the query params. + """ + songs = self.collection.find({"artists": {"$regex": query, "$options": "i"}}) return convert_to_json(songs) - def find_song_by_title(self, query): - self.collection.create_index([('title', pymongo.TEXT)]) - song = self.collection.find( - {'title': {'$regex': query, '$options': 'i'}}) + def find_song_by_title(self, query: str) -> list: + """ + Finds all the tracks matching the title in the query params. + """ + self.collection.create_index([("title", pymongo.TEXT)]) + song = self.collection.find({"title": {"$regex": query, "$options": "i"}}) return convert_to_json(song) - def find_songs_by_album(self, name, artist): - songs = self.collection.find({'album': name, 'album_artist': artist}) + def find_songs_by_album(self, name: str, artist: str) -> list: + """ + Returns all the tracks exactly matching the album in the query params. + """ + songs = self.collection.find({"album": name, "albumartist": artist}) return convert_to_json(songs) - def find_songs_by_folder(self, query): - songs = self.collection.find({'folder': query}).sort( - 'title', pymongo.ASCENDING) + def find_songs_by_folder(self, query: str) -> list: + """ + Returns a sorted list of all the tracks exactly matching the folder in the query params + """ + songs = self.collection.find({"folder": query}).sort("title", pymongo.ASCENDING) return convert_to_json(songs) - def find_songs_by_folder_og(self, query): - songs = self.collection.find({'folder': query}) + def find_songs_by_folder_og(self, query: str) -> list: + """ + Returns an unsorted list of all the tracks exactly matching the folder in the query params + """ + songs = self.collection.find({"folder": query}) return convert_to_json(songs) - def find_songs_by_artist(self, query): - songs = self.collection.find({'artists': query}) + def find_songs_by_artist(self, query: str) -> list: + """ + Returns a list of all the tracks exactly matching the artists in the query params. + """ + songs = self.collection.find({"artists": query}) return convert_to_json(songs) - def find_songs_by_album_artist(self, query): + def find_songs_by_albumartist(self, query: str): + """ + Returns a list of all the tracks containing the albumartist in the query params. + """ songs = self.collection.find( - {'album_artist': {'$regex': query, '$options': 'i'}}) + {"albumartist": {"$regex": query, "$options": "i"}} + ) return convert_to_json(songs) - def find_song_by_path(self, path): - song = self.collection.find_one({'filepath': path}) + def find_song_by_path(self, path: str) -> dict: + """ + Returns a single track matching the filepath in the query params. + """ + song = self.collection.find_one({"filepath": path}) return convert_one_to_json(song) - def remove_song_by_filepath(self, filepath): + def remove_song_by_filepath(self, filepath: str): + """ + Removes a single track from the database. Returns a boolean indicating success or failure of the operation. + """ try: - self.collection.delete_one({'filepath': filepath}) + self.collection.delete_one({"filepath": filepath}) return True except: return False @@ -124,10 +193,14 @@ class AllSongs(Mongo): @dataclass class Track: - id: str + """ + Track class + """ + + track_id: str title: str artists: str - album_artist: str + albumartist: str album: str filepath: str folder: str @@ -136,9 +209,9 @@ class Track: genre: str bitrate: int image: str + tracknumber: int + discnumber: int def __post_init__(self): - self.artists = self.artists.split(', ') + self.artists = self.artists.split(", ") self.image = "http://127.0.0.1:8900/images/thumbnails/" + self.image - - diff --git a/src/components/RightSideBar/Home/Main.vue b/src/components/RightSideBar/Home/Main.vue index ee3e13c8..fd53c71d 100644 --- a/src/components/RightSideBar/Home/Main.vue +++ b/src/components/RightSideBar/Home/Main.vue @@ -1,5 +1,5 @@ <template> - <div class="r-home"> + <div class="r-home rounded border"> <NowPlaying /> <Recommendations /> </div> @@ -9,6 +9,8 @@ .r-home { height: 100%; width: 31rem; + background-color: $card-dark; + padding: $small; } </style> diff --git a/src/components/RightSideBar/Main.vue b/src/components/RightSideBar/Main.vue index 4a25ba26..a6391a8b 100644 --- a/src/components/RightSideBar/Main.vue +++ b/src/components/RightSideBar/Main.vue @@ -1,7 +1,7 @@ <template> <div class="r-sidebar"> <div class="grid"> - <div class="r-content rounded"> + <div class="r-content"> <div class="r-dash" v-show="current_tab == tabs.home"> <DashBoard /> </div> @@ -63,7 +63,6 @@ function changeTab(tab) { .r-content { grid-area: content; width: 31rem; - overflow: hidden; // @include tablet-landscape { // display: none; diff --git a/src/components/RightSideBar/NowPlaying.vue b/src/components/RightSideBar/NowPlaying.vue index 2273be71..b44c9bec 100644 --- a/src/components/RightSideBar/NowPlaying.vue +++ b/src/components/RightSideBar/NowPlaying.vue @@ -108,13 +108,13 @@ export default { #title { margin: 0; - width: 22rem; + width: 20rem; color: #fff; } #artist { font-size: small; - width: 22rem; + width: 20rem; color: $highlight-blue; } diff --git a/src/components/RightSideBar/Queue.vue b/src/components/RightSideBar/Queue.vue index 76909087..46e47016 100644 --- a/src/components/RightSideBar/Queue.vue +++ b/src/components/RightSideBar/Queue.vue @@ -20,16 +20,16 @@ </div> </div> <div class="scrollable-r border rounded"> - <TrackItem v-for="song in queue" :key="song.id" :track="song" /> + <TrackItem v-for="song in queue" :key="song.track_id" :track="song" /> </div> </div> </div> </template> <script> -import { ref, toRefs } from "@vue/reactivity"; import perks from "@/composables/perks.js"; import audio from "@/composables/playAudio.js"; +import { ref, toRefs } from "@vue/reactivity"; import { watch } from "@vue/runtime-core"; import TrackItem from "../shared/TrackItem.vue"; @@ -120,10 +120,9 @@ export default { .r-grid { position: relative; - height: 100%; + height: calc(100% - 2rem); display: grid; grid-template-rows: min-content; - padding-bottom: 2.5rem; .scrollable-r { height: 100%; diff --git a/src/components/Search/TracksGrid.vue b/src/components/Search/TracksGrid.vue index 1c5dc791..b447c390 100644 --- a/src/components/Search/TracksGrid.vue +++ b/src/components/Search/TracksGrid.vue @@ -6,7 +6,7 @@ <tbody> <TrackItem v-for="track in props.tracks" - :key="track.id" + :key="track.track_id" :track="track" /> </tbody> diff --git a/src/components/shared/SongItem.vue b/src/components/shared/SongItem.vue index bd387aff..589162c1 100644 --- a/src/components/shared/SongItem.vue +++ b/src/components/shared/SongItem.vue @@ -1,5 +1,5 @@ <template> - <tr class="songlist-item" :class="{ current: current.id == song.id }"> + <tr class="songlist-item" :class="{ current: current.track_id == song.track_id }"> <td class="index">{{ index }}</td> <td class="flex" @click="emitUpdate(song)"> <div @@ -8,7 +8,7 @@ > <div class="now-playing-track image" - v-if="current.id == song.id" + v-if="current.track_id == song.track_id" :class="{ active: is_playing, not_active: !is_playing }" ></div> </div> diff --git a/src/components/shared/TrackItem.vue b/src/components/shared/TrackItem.vue index b14a355b..81ec4871 100644 --- a/src/components/shared/TrackItem.vue +++ b/src/components/shared/TrackItem.vue @@ -3,7 +3,7 @@ class="track-item h-1" @click="playThis(props.track)" :class="{ - currentInQueue: current.id == props.track.id, + currentInQueue: current.track_id == props.track.track_id, }" > <div @@ -14,7 +14,7 @@ > <div class="now-playing-track image" - v-if="current.id == props.track.id" + v-if="current.track_id == props.track.track_id" :class="{ active: is_playing, not_active: !is_playing }" ></div> </div> diff --git a/src/composables/perks.js b/src/composables/perks.js index 42b3d566..0c791ab0 100644 --- a/src/composables/perks.js +++ b/src/composables/perks.js @@ -1,9 +1,9 @@ import { ref } from "@vue/reactivity"; import { watch } from "@vue/runtime-core"; - import media from "./mediaNotification.js"; -import state from "./state.js"; import playAudio from "./playAudio.js"; +import state from "./state.js"; + const current = ref(state.current); @@ -50,7 +50,7 @@ function updateNext(song_) { } function updatePrev(song) { - const index = state.queue.value.findIndex((item) => item.id === song.id); + const index = state.queue.value.findIndex((item) => item.id === song.track_id); if (index == 0) { prev.value = queue.value[queue.value.length - 1]; diff --git a/src/composables/playAudio.js b/src/composables/playAudio.js index d4a15b64..76fb9ac4 100644 --- a/src/composables/playAudio.js +++ b/src/composables/playAudio.js @@ -11,6 +11,7 @@ const playing = ref(state.is_playing); const url = "http://0.0.0.0:8901/"; const playAudio = (path) => { + console.log(path) const elem = document.getElementById('progress') const full_path = url + encodeURIComponent(path);