add featured artists in albumview

This commit is contained in:
geoffrey45 2022-01-15 18:18:55 +03:00
parent 1b9e6821d6
commit a720891c20
13 changed files with 166 additions and 148 deletions

View File

@ -13,7 +13,7 @@ all_the_f_music = helpers.getAllSongs()
def initialize() -> None:
helpers.create_config_dir()
# helpers.check_for_new_songs()
helpers.check_for_new_songs()
initialize()
@ -54,9 +54,8 @@ def search_by_title():
album['image'] = "image"
for song in ar:
a = song["artists"].split(', ')
for artist in a:
for artist in song["artists"]:
if query.lower() in artist.lower():
artist_obj = {
@ -75,30 +74,34 @@ def x():
return "🎸"
@bp.route("/folder/artists")
def get_folder_artists():
dir = request.args.get('dir')
@bp.route("/album/<album>/<artist>/artists")
@cache.cached()
def get_album_artists(album, artist):
album = album.replace('|', '/')
artist = artist.replace('|', '/')
tracks = []
songs = instances.songs_instance.find_songs_by_folder(dir)
without_duplicates = helpers.remove_duplicates(songs)
for track in all_the_f_music:
if track["album"] == album and track["album_artist"] == artist:
tracks.append(track)
artists = []
for song in without_duplicates:
this_artists = song['artists'].split(', ')
for artist in this_artists:
for track in tracks:
print(track['artists'])
for artist in track['artists']:
if artist not in artists:
artists.append(artist)
final_artists = []
for artist in artists[:15]:
artist_obj = instances.artist_instance.find_artists_by_name(artist)
if artist_obj != []:
final_artists.append(artist_obj)
for artist in artists:
artist_obj = {
"name": artist,
"image": "http://127.0.0.1:8900/images/artists/" + artist.replace('/', '::') + ".jpg"
}
final_artists.append(artist_obj)
return {'artists': final_artists}
@ -106,6 +109,7 @@ def get_folder_artists():
@bp.route("/populate/images")
def populate_images():
functions.populate_images()
return "Done"
@bp.route("/artist/<artist>")
@ -129,9 +133,6 @@ def getArtistData(artist: str):
albums = instances.songs_instance.find_songs_by_album_artist(artist)
for song in songs:
song['artists'] = song['artists'].split(', ')
for song in albums:
if song['album'] not in artist_albums:
artist_albums.append(song['album'])
@ -200,12 +201,6 @@ def getFolderTree(folder: str = None):
if x['folder'] == req_dir:
songs.append(x)
for song in songs:
try:
song['artists'] = song['artists'].split(', ')
except:
pass
return {"files": helpers.remove_duplicates(songs), "folders": sorted(folders, key=lambda i: i['name'])}
@bp.route('/qwerty')
@ -215,9 +210,7 @@ def populateArtists():
artists = []
for song in all_songs:
artist = song['artists'].split(', ')
for a in artist:
for a in song['artists']:
a_obj = {
"name": a,
}
@ -252,11 +245,11 @@ def getAlbumSongs(query: str):
album = query.split('::')[0].replace('|', '/')
artist = query.split('::')[1].replace('|', '/')
songs = instances.songs_instance.find_songs_by_album(album, artist)
songs = []
for song in songs:
song['artists'] = song['artists'].split(', ')
song['image'] = "http://127.0.0.1:8900/images/thumbnails/" + song['image']
for track in all_the_f_music:
if track['album'] == album and track['album_artist'] == artist:
songs.append(track)
album_obj = {
"name": album,

View File

@ -2,13 +2,14 @@
This module contains larger functions for the server
"""
import time
from progress.bar import Bar
import requests
import os
from mutagen.flac import MutagenError
from app import helpers
from app import instances
from app import api
def populate():
'''
@ -18,6 +19,7 @@ def populate():
also checks if the album art exists in the image path, if not tries to
extract it.
'''
print('\nchecking for new tracks')
files = helpers.run_fast_scandir(helpers.home_dir, [".flac", ".mp3"])[1]
for file in files:
@ -36,8 +38,8 @@ def populate():
helpers.getTags(file)
except MutagenError:
pass
return {'msg': 'updated everything'}
api.all_the_f_music = helpers.getAllSongs()
print('\ncheck done')
def populate_images():
@ -54,35 +56,29 @@ def populate_images():
bar = Bar('Processing images', max=len(artists))
for artist in artists:
file_path = helpers.app_dir + '/images/artists/' + artist + '.jpg'
file_path = helpers.app_dir + '/images/artists/' + \
artist.replace('/', '::') + '.jpg'
if not os.path.exists(file_path):
url = 'https://api.deezer.com/search/artist?q={}'.format(artist)
response = requests.get(url)
try:
response = requests.get(url)
except:
print('\n sleeping for 5 seconds')
time.sleep(5)
response = requests.get(url)
data = response.json()
try:
image_path = data['data'][0]['picture_xl']
img_data = data['data'][0]['picture_xl']
except:
image_path = None
img_data = None
if image_path is not None:
try:
helpers.save_image(image_path, file_path)
artist_obj = {
'name': artist
}
instances.artist_instance.insert_artist(artist_obj)
except:
pass
else:
pass
if img_data is not None:
helpers.save_image(img_data, file_path)
bar.next()
bar.finish()
artists_in_db = instances.artist_instance.get_all_artists()
return {'sample': artists_in_db[:25]}

View File

@ -268,8 +268,11 @@ def getAllSongs() -> None:
except FileNotFoundError:
instances.songs_instance.remove_song_by_filepath(
os.path.join(home_dir, track['filepath']))
if track['image'] is not None:
track['image'] = "http://127.0.0.1:8900/images/thumbnails/" + \
track['image']
if track['artists'] is not None:
track['artists'] = track['artists'].split(', ')
return tracks

View File

@ -52,6 +52,7 @@ a {
button {
border: none;
outline: none;
color: inherit;
font-size: 1rem;
cursor: pointer;

View File

@ -5,9 +5,11 @@
<div class="icon"></div>
Play
</button>
<div class="ellip text">
<div class="text">
<div class="icon image"></div>
{{ path.split("/").splice(-1) + "" }}
<div class="ellip">
{{ path.split("/").splice(-1) + "" }}
</div>
</div>
</div>
<div class="search">
@ -25,17 +27,17 @@
<script>
import perks from "@/composables/perks.js";
import state from "@/composables/state.js"
import state from "@/composables/state.js";
export default {
props: ["path", "first_song"],
setup() {
function playFolder(song) {
perks.updateQueue(song, "folder")
perks.updateQueue(song, "folder");
}
return {
playFolder,
search_query: state.search_query
search_query: state.search_query,
};
},
};
@ -60,7 +62,7 @@ export default {
max-width: 20rem;
width: 100%;
border: 1px solid $separator;
border-radius: .5rem;
border-radius: 0.5rem;
padding-left: 1rem;
background-color: #46454500;
color: #fff;
@ -96,14 +98,18 @@ export default {
}
.text {
position: relative;
display: flex;
align-items: center;
border-radius: $small;
background-color: rgb(24, 22, 22);
padding: $small;
padding-left: 2.25rem;
.icon {
position: absolute;
left: $small;
height: 1.5rem;
width: 1.5rem;
background-image: url(../../assets/icons/folder.svg);

View File

@ -39,7 +39,7 @@ import { ref } from "@vue/reactivity";
import { onMounted, onUnmounted } from "@vue/runtime-core";
import SongItem from "../SongItem.vue";
import getAlbum from "@/composables/getAlbum.js";
import album from "@/composables/album.js";
import perks from "@/composables/perks.js";
import state from "@/composables/state.js";
import { useRouter, useRoute } from "vue-router";
@ -104,7 +104,7 @@ export default {
function loadAlbum(title, album_artist) {
state.loading.value = true;
getAlbum(title, album_artist).then((data) => {
album.getAlbumTracks(title, album_artist).then((data) => {
state.album_song_list.value = data.songs;
state.album_info.value = data.info;
@ -189,7 +189,7 @@ th {
th {
text-transform: uppercase;
font-weight: normal;
display: none;
// display: none;
}
td .artist {

View File

@ -4,7 +4,7 @@
<div class="nav-button" id="home-button">
<div class="in">
<div class="nav-icon image" id="home-icon"></div>
<span id="text">Home</span>
<span>Home</span>
</div>
</div>
</router-link>
@ -13,7 +13,7 @@
<div class="nav-button" id="album-button">
<div class="in">
<div class="nav-icon image" id="album-icon"></div>
<span id="text">Albums</span>
<span>Albums</span>
</div>
</div>
</router-link>
@ -22,7 +22,7 @@
<div class="nav-button" id="artists-button">
<div class="in">
<div class="nav-icon image" id="artists-icon"></div>
<span id="text">Artists</span>
<span>Artists</span>
</div>
</div>
</router-link>
@ -31,7 +31,7 @@
<div class="nav-button" id="playlists-button">
<div class="in">
<div class="nav-icon image" id="playlists-icon"></div>
<span id="text">Playlist</span>
<span>Playlist</span>
</div>
</div>
</router-link>
@ -40,7 +40,7 @@
<div class="nav-button" id="mixes-button">
<div class="in">
<div class="nav-icon image" id="mixes-icon"></div>
<span id="text">Mixes</span>
<span>Mixes</span>
</div>
</div>
</router-link>
@ -49,7 +49,7 @@
<div class="nav-button" id="folders-button">
<div class="in">
<div class="nav-icon image" id="folders-icon"></div>
<span id="text">Folders</span>
<span>Folders</span>
</div>
</div>
</router-link>
@ -58,7 +58,7 @@
<div class="nav-button" id="folders-button">
<div class="in">
<div class="nav-icon image" id="settings-icon"></div>
<span id="text">Settings</span>
<span>Settings</span>
</div>
</div>
</router-link>
@ -97,7 +97,6 @@ export default {
display: flex;
align-items: flex-start;
justify-content: flex-start;
background-color: transparent;
height: 100%;
padding: 0.6rem 0 0.6rem 0;
@ -106,10 +105,12 @@ export default {
}
.nav-icon {
height: 1.5rem;
width: 1.5rem;
height: 2rem;
width: 2rem;
margin-right: 0.5rem;
margin-left: 10px;
margin-left: 0.6rem;
border-radius: $small;
background-color: rgb(26, 24, 24);
}
.in {
@ -117,6 +118,16 @@ export default {
align-items: center;
}
#home-icon,
#album-icon,
#artists-icon,
#playlists-icon,
#mixes-icon,
#folders-icon,
#settings-icon {
background-size: 1.5rem;
}
#home-icon {
background-image: url(../../assets/icons/home.svg);
}
@ -125,10 +136,6 @@ export default {
background-image: url(../../assets/icons/album.svg);
}
#text {
margin-top: 5px;
}
#artists-icon {
background-image: url(../../assets/icons/artist.svg);
}

View File

@ -1,10 +1,10 @@
<template>
<div class="f-artists">
<div class="xcontrols">
<div class="prev" @click="scrollLeftX"></div>
<div class="next" @click="scrollRightX"></div>
<div class="prev" @click="scrollLeft"></div>
<div class="next" @click="scrollRight"></div>
</div>
<div class="artists" ref="artists_dom" v-on:mouseover="say">
<div class="artists" ref="artists_dom" v-on:mouseover="scrollArtists">
<div class="artist c1">
<div class="blur"></div>
<div class="s2"></div>
@ -12,8 +12,11 @@
</div>
<div class="artist" v-for="artist in artists" :key="artist">
<div>
<div class="artist-image image"></div>
<p class="artist-name ellipsis">{{ artist }}</p>
<div
class="artist-image image"
:style="{ backgroundImage: `url('${artist.image}')` }"
></div>
<p class="artist-name ellipsis">{{ artist.name }}</p>
<div class="a-circle"></div>
</div>
</div>
@ -24,24 +27,11 @@
import { ref } from "@vue/reactivity";
export default {
props: ["artists"],
setup() {
const artists = [
"Michael John Montgomery",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
];
const artists_dom = ref(null);
const scrollLeftX = () => {
const scrollLeft = () => {
const dom = artists_dom.value;
dom.scrollBy({
left: -700,
@ -49,7 +39,7 @@ export default {
});
};
const scrollRightX = () => {
const scrollRight = () => {
const dom = artists_dom.value;
dom.scrollBy({
left: 700,
@ -64,7 +54,7 @@ export default {
});
};
const say = () => {
const scrollArtists = () => {
artists_dom.value.addEventListener("wheel", (e) => {
e.preventDefault();
scroll(e);
@ -72,11 +62,10 @@ export default {
};
return {
artists,
artists_dom,
say,
scrollLeftX,
scrollRightX,
scrollArtists,
scrollLeft,
scrollRight,
};
},
};
@ -87,7 +76,7 @@ export default {
position: relative;
height: 13em;
width: calc(100%);
background-color: #1f1e1d;
background-color: $card-dark;
padding: $small;
border-radius: $small;
user-select: none;
@ -127,7 +116,7 @@ export default {
.next:hover,
.prev:hover {
background-color: rgb(3, 1, 1);
background-color: $blue;
transition: all 0.5s ease;
}
}
@ -156,7 +145,7 @@ export default {
width: 9em;
height: 9em;
border-radius: $small;
background-color: #fd5c63;
background-color: #0f0e0e;
display: flex;
align-items: center;
justify-content: center;
@ -189,11 +178,8 @@ export default {
.f-artists .c1 {
position: relative;
background: rgb(145, 42, 56);
background: rgb(16, 25, 51);
width: 15em;
background-image: url(../../assets/images/gradient1.gif);
overflow: hidden;
margin-left: -0.1rem;
&:hover > .s2 {
background: rgba(53, 53, 146, 0.8);
@ -206,23 +192,11 @@ export default {
position: absolute;
bottom: -2rem;
margin-left: 0.5rem;
z-index: 1;
font-size: 2rem;
font-weight: 700;
color: #ffffff;
}
.blur {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0);
backdrop-filter: blur(40px);
-webkit-backdrop-filter: blur(40px);
-moz-backdrop-filter: blur(40px);
border-radius: $small;
}
.s2 {
position: absolute;
left: -2em;

View File

@ -62,7 +62,6 @@ export default {
}
function emitLoadAlbum(title, artist){
console.log(title, artist)
emit("loadAlbum", title, artist)
}

44
src/composables/album.js Normal file
View File

@ -0,0 +1,44 @@
let base_uri = "http://127.0.0.1:9876";
const getAlbumTracks = async (name, artist) => {
const res = await fetch(
base_uri +
"/albums/" +
encodeURIComponent(name.replaceAll("/", "|")) +
"::" +
encodeURIComponent(artist.replaceAll("/", "|"))
);
if (!res.ok) {
const message = `An error has occured: ${res.status}`;
throw new Error(message);
}
const data = await res.json();
return data;
};
const getAlbumArtists = async (name, artist) => {
const res = await fetch(
base_uri +
"/album/" +
encodeURIComponent(name.replaceAll("/", "|")) +
"/" +
encodeURIComponent(artist.replaceAll("/", "|")) +
"/artists"
);
if (!res.ok) {
const message = `An error has occured: ${res.status}`;
throw new Error(message);
}
const data = await res.json();
return data.artists;
};
export default {
getAlbumTracks,
getAlbumArtists,
};

View File

@ -1,16 +0,0 @@
let base_uri = "http://127.0.0.1:9876";
const getAlbum = async (name, artist) => {
const res = await fetch(base_uri + "/albums/" + encodeURIComponent(name.replaceAll("/", "|")) + "::" + encodeURIComponent(artist.replaceAll("/", "|")));
if (!res.ok) {
const message = `An error has occured: ${res.status}`;
throw new Error(message);
}
const data = await res.json();
return data;
};
export default getAlbum;

View File

@ -33,8 +33,9 @@ const prev = ref({
const album_song_list = ref([])
const album_info = ref([])
const album_artists = ref([])
const filters = ref([]);
const magic_flag = ref(false);
const loading = ref(false);
@ -59,5 +60,6 @@ export default {
search_albums,
search_artists,
album_song_list,
album_info
album_info,
album_artists
};

View File

@ -8,7 +8,7 @@
<SongList :songs="album_songs" />
</div>
<div class="separator" id="av-sep"></div>
<FeaturedArtists />
<FeaturedArtists :artists="artists" />
<div class="separator" id="av-sep"></div>
<AlbumBio />
<div class="separator" id="av-sep"></div>
@ -27,7 +27,7 @@ import FromTheSameArtist from "../components/AlbumView/FromTheSameArtist.vue";
import SongList from "../components/FolderView/SongList.vue";
import FeaturedArtists from "../components/PlaylistView/FeaturedArtists.vue";
import getAlbum from "../composables/getAlbum.js";
import album from "@/composables/album.js";
import state from "@/composables/state.js";
import { onUnmounted } from "@vue/runtime-core";
@ -46,23 +46,32 @@ export default {
onMounted(() => {
if (!state.album_song_list.value.length) {
getAlbum(title, album_artists).then((data) => {
album.getAlbumTracks(title, album_artists).then((data) => {
state.album_song_list.value = data.songs;
state.album_info.value = data.info;
state.loading.value = false;
});
}
if (state.album_artists.value.length == 0) {
album.getAlbumArtists(title, album_artists).then((data) => {
state.album_artists.value = data;
console.log(state.album_artists.value)
});
}
});
onUnmounted(() => {
state.album_song_list.value = [];
state.album_info.value = {};
state.album_artists.value = [];
});
return {
album_songs: state.album_song_list,
album_info: state.album_info,
artists: state.album_artists,
};
},
};