mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-06-07 03:35:35 +00:00
✅ complete project teardown
This commit is contained in:
parent
b930fc0ca6
commit
25f79d8a20
@ -1,44 +0,0 @@
|
||||
from typing import List
|
||||
from app import models, instances, functions
|
||||
|
||||
all_albums: List[models.Album] = []
|
||||
|
||||
|
||||
def create_all_albums() -> List[models.Album]:
|
||||
"""Creates album objects for all albums"""
|
||||
albums: list[models.Album] = []
|
||||
|
||||
for album in instances.album_instance.get_all_albums():
|
||||
albums.append(models.Album(album))
|
||||
|
||||
return albums
|
||||
|
||||
|
||||
def get_album_duration(album: List[models.Track]) -> int:
|
||||
"""
|
||||
Gets the duration of an album.
|
||||
"""
|
||||
|
||||
album_duration = 0
|
||||
|
||||
for track in album:
|
||||
try:
|
||||
album_duration += track.length
|
||||
except AttributeError:
|
||||
album_duration += track["length"]
|
||||
|
||||
return album_duration
|
||||
|
||||
|
||||
def get_album_image(album: list) -> str:
|
||||
"""
|
||||
Gets the image of an album.
|
||||
"""
|
||||
|
||||
for track in album:
|
||||
img = functions.extract_thumb(track["filepath"])
|
||||
|
||||
if img is not None:
|
||||
return img
|
||||
|
||||
return functions.use_defaults()
|
64
server/app/albumslib.py
Normal file
64
server/app/albumslib.py
Normal file
@ -0,0 +1,64 @@
|
||||
from typing import List
|
||||
from app import models, functions
|
||||
from app import trackslib
|
||||
|
||||
ALBUMS: List[models.Album] = []
|
||||
|
||||
|
||||
def create_all_albums() -> List[models.Track]:
|
||||
"""
|
||||
Creates album objects for all albums and returns
|
||||
a list of track objects
|
||||
"""
|
||||
albums: list[models.Album] = functions.get_all_albums()
|
||||
|
||||
ALBUMS.clear()
|
||||
ALBUMS.extend(albums)
|
||||
trackslib.create_all_tracks()
|
||||
return trackslib.TRACKS
|
||||
|
||||
|
||||
def get_album_duration(album: list) -> int:
|
||||
"""
|
||||
Gets the duration of an album.
|
||||
"""
|
||||
|
||||
album_duration = 0
|
||||
|
||||
for track in album:
|
||||
album_duration += track["length"]
|
||||
|
||||
return album_duration
|
||||
|
||||
|
||||
def get_album_image(album: list) -> str:
|
||||
"""
|
||||
Gets the image of an album.
|
||||
"""
|
||||
|
||||
for track in album:
|
||||
img = functions.extract_thumb(track["filepath"])
|
||||
|
||||
if img is not None:
|
||||
return img
|
||||
|
||||
return functions.use_defaults()
|
||||
|
||||
|
||||
def find_album(albumtitle, artist):
|
||||
for album in ALBUMS:
|
||||
if album.album == albumtitle and album.artist == artist:
|
||||
return album
|
||||
|
||||
|
||||
def search_albums_by_name(query):
|
||||
"""
|
||||
Searches albums by album name.
|
||||
"""
|
||||
albums: List[models.Album] = []
|
||||
|
||||
for album in ALBUMS:
|
||||
if query in album.album:
|
||||
albums.append(album)
|
||||
|
||||
return albums
|
@ -1,31 +1,30 @@
|
||||
from crypt import methods
|
||||
import os
|
||||
from pprint import pprint
|
||||
import urllib
|
||||
from typing import List
|
||||
from flask import Blueprint, request, send_file
|
||||
|
||||
from app import functions, instances, helpers, cache, models
|
||||
from app import functions, instances, helpers, cache, models, prep
|
||||
from app import albumslib, searchlib
|
||||
from app import trackslib
|
||||
|
||||
bp = Blueprint("api", __name__, url_prefix="")
|
||||
|
||||
home_dir = helpers.home_dir
|
||||
all_the_f_music = albumslib.create_all_albums()
|
||||
|
||||
|
||||
@helpers.background
|
||||
def initialize() -> None:
|
||||
"""
|
||||
Runs all the necessary setup functions.
|
||||
"""
|
||||
helpers.create_config_dir()
|
||||
helpers.reindex_tracks()
|
||||
helpers.start_watchdog()
|
||||
prep.create_config_dir()
|
||||
functions.reindex_tracks()
|
||||
functions.start_watchdog()
|
||||
|
||||
|
||||
initialize()
|
||||
|
||||
all_the_f_albums = helpers.create_all_albums()
|
||||
all_the_f_music = helpers.create_all_tracks()
|
||||
|
||||
|
||||
@bp.route("/")
|
||||
def say_hi():
|
||||
@ -33,32 +32,7 @@ def say_hi():
|
||||
return "^ _ ^"
|
||||
|
||||
|
||||
def get_tracks(query: str) -> List[models.Track]:
|
||||
"""
|
||||
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[models.Track]:
|
||||
"""
|
||||
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[models.Track]:
|
||||
"""
|
||||
Gets all songs with a given artist.
|
||||
"""
|
||||
return [
|
||||
track
|
||||
for track in all_the_f_music
|
||||
if artist.lower() in str(track.artists).lower()
|
||||
]
|
||||
|
||||
|
||||
search_results = {
|
||||
SEARCH_RESULTS = {
|
||||
"tracks": [],
|
||||
"albums": [],
|
||||
"artists": [],
|
||||
@ -66,31 +40,16 @@ search_results = {
|
||||
|
||||
|
||||
@bp.route("/search")
|
||||
def search_by_title():
|
||||
def search():
|
||||
"""
|
||||
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 = []
|
||||
albums = searchlib.get_search_albums(query)
|
||||
artists_dicts = []
|
||||
search_results.clear()
|
||||
|
||||
for song in albums:
|
||||
album_obj = {
|
||||
"name": song.album,
|
||||
"artist": song.albumartist,
|
||||
}
|
||||
|
||||
if album_obj not in albums_dicts:
|
||||
albums_dicts.append(album_obj)
|
||||
|
||||
for album in albums_dicts:
|
||||
for track in albums:
|
||||
if album["name"] == track.album:
|
||||
album["image"] = track.image
|
||||
artist_tracks = get_artists(query)
|
||||
artist_tracks = searchlib.get_artists(query)
|
||||
|
||||
for song in artist_tracks:
|
||||
for artist in song.artists:
|
||||
@ -106,17 +65,18 @@ def search_by_title():
|
||||
if artist_obj not in artists_dicts:
|
||||
artists_dicts.append(artist_obj)
|
||||
|
||||
tracks = helpers.remove_duplicates(get_tracks(query))
|
||||
tracks = [*tracks, *artist_tracks]
|
||||
_tracks = searchlib.get_tracks(query)
|
||||
tracks = [*_tracks, *artist_tracks]
|
||||
|
||||
search_results["tracks"] = tracks
|
||||
search_results["albums"] = albums_dicts
|
||||
search_results["artists"] = artists_dicts
|
||||
SEARCH_RESULTS.clear()
|
||||
SEARCH_RESULTS["tracks"] = tracks
|
||||
SEARCH_RESULTS["albums"] = albums
|
||||
SEARCH_RESULTS["artists"] = artists_dicts
|
||||
|
||||
return {
|
||||
"data": [
|
||||
{"tracks": tracks[:5], "more": len(tracks) > 5},
|
||||
{"albums": albums_dicts[:6], "more": len(albums_dicts) > 6},
|
||||
{"albums": albums[:6], "more": len(albums) > 6},
|
||||
{"artists": artists_dicts[:6], "more": len(artists_dicts) > 6},
|
||||
]
|
||||
}
|
||||
@ -132,20 +92,20 @@ def search_load_more():
|
||||
|
||||
if type == "tracks":
|
||||
return {
|
||||
"tracks": search_results["tracks"][start : start + 5],
|
||||
"more": len(search_results["tracks"]) > start + 5,
|
||||
"tracks": SEARCH_RESULTS["tracks"][start : start + 5],
|
||||
"more": len(SEARCH_RESULTS["tracks"]) > start + 5,
|
||||
}
|
||||
|
||||
elif type == "albums":
|
||||
return {
|
||||
"albums": search_results["albums"][start : start + 6],
|
||||
"more": len(search_results["albums"]) > start + 6,
|
||||
"albums": SEARCH_RESULTS["albums"][start : start + 6],
|
||||
"more": len(SEARCH_RESULTS["albums"]) > start + 6,
|
||||
}
|
||||
|
||||
elif type == "artists":
|
||||
return {
|
||||
"artists": search_results["artists"][start : start + 6],
|
||||
"more": len(search_results["artists"]) > start + 6,
|
||||
"artists": SEARCH_RESULTS["artists"][start : start + 6],
|
||||
"more": len(SEARCH_RESULTS["artists"]) > start + 6,
|
||||
}
|
||||
|
||||
|
||||
@ -314,27 +274,10 @@ def get_album_tracks():
|
||||
album = data["album"]
|
||||
artist = data["artist"]
|
||||
|
||||
songs = []
|
||||
songs = trackslib.get_album_tracks(album, artist)
|
||||
album = albumslib.find_album(album, artist)
|
||||
|
||||
for track in all_the_f_music:
|
||||
if track.albumartist == artist and track.album == album:
|
||||
songs.append(track)
|
||||
|
||||
songs = helpers.remove_duplicates(songs)
|
||||
|
||||
album_obj = {
|
||||
"name": album,
|
||||
"count": len(songs),
|
||||
"duration": helpers.get_album_duration(songs),
|
||||
"image": songs[0].image,
|
||||
"date": songs[0].date,
|
||||
"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}
|
||||
|
||||
|
||||
@bp.route("/album/<title>/<artist>/bio")
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
This module contains larger functions for the server
|
||||
This module contains functions for the server
|
||||
"""
|
||||
|
||||
import time
|
||||
@ -7,6 +7,7 @@ import os
|
||||
from io import BytesIO
|
||||
import random
|
||||
import datetime
|
||||
from typing import List
|
||||
import mutagen
|
||||
import urllib
|
||||
|
||||
@ -19,7 +20,31 @@ from PIL import Image
|
||||
|
||||
from app import helpers
|
||||
from app import instances
|
||||
from app import api, settings
|
||||
from app import api, settings, watchdoge, models, trackslib
|
||||
from app import albumslib
|
||||
|
||||
|
||||
def reindex_tracks():
|
||||
"""
|
||||
Checks for new songs every 5 minutes.
|
||||
"""
|
||||
flag = False
|
||||
|
||||
while flag is False:
|
||||
populate()
|
||||
get_all_albums()
|
||||
populate_images()
|
||||
# functions.save_t_colors()
|
||||
|
||||
time.sleep(300)
|
||||
|
||||
|
||||
@helpers.background
|
||||
def start_watchdog():
|
||||
"""
|
||||
Starts the file watcher.
|
||||
"""
|
||||
watchdoge.watch.run()
|
||||
|
||||
|
||||
def populate():
|
||||
@ -41,7 +66,7 @@ def populate():
|
||||
if tags is not None:
|
||||
instances.songs_instance.insert_song(tags)
|
||||
|
||||
api.all_the_f_music = helpers.create_all_tracks()
|
||||
albumslib.create_all_albums()
|
||||
|
||||
print("\n check done")
|
||||
end = time.time()
|
||||
@ -340,11 +365,12 @@ def get_album_bio(title: str, albumartist: str):
|
||||
return bio
|
||||
|
||||
|
||||
def get_all_albums():
|
||||
def get_all_albums() -> List[models.Album]:
|
||||
print("processing albums started ...")
|
||||
|
||||
all_tracks = instances.songs_instance.get_all_songs()
|
||||
album_dicts = []
|
||||
albums = []
|
||||
|
||||
for track in all_tracks:
|
||||
album_dict = {
|
||||
@ -364,14 +390,14 @@ def get_all_albums():
|
||||
]
|
||||
|
||||
album["count"] = len(album_tracks)
|
||||
album["duration"] = helpers.get_album_duration(album_tracks)
|
||||
album["duration"] = albumslib.get_album_duration(album_tracks)
|
||||
album["date"] = album_tracks[0]["date"]
|
||||
album["artistimage"] = urllib.parse.quote_plus(
|
||||
album_tracks[0]["albumartist"] + ".webp"
|
||||
)
|
||||
|
||||
album["image"] = helpers.get_album_image(album_tracks)
|
||||
album["image"] = albumslib.get_album_image(album_tracks)
|
||||
|
||||
instances.album_instance.insert_album(album)
|
||||
albums.append(album)
|
||||
|
||||
print("done processing albums")
|
||||
return [models.Album(album) for album in albums]
|
||||
|
@ -34,28 +34,6 @@ def background(func):
|
||||
return background_func
|
||||
|
||||
|
||||
@background
|
||||
def reindex_tracks():
|
||||
"""
|
||||
Checks for new songs every 5 minutes.
|
||||
"""
|
||||
flag = False
|
||||
|
||||
while flag is False:
|
||||
functions.populate()
|
||||
functions.get_all_albums()
|
||||
# functions.populate_images()
|
||||
# functions.save_t_colors()
|
||||
|
||||
time.sleep(300)
|
||||
|
||||
|
||||
@background
|
||||
def start_watchdog():
|
||||
"""
|
||||
Starts the file watcher.
|
||||
"""
|
||||
watchdoge.watch.run()
|
||||
|
||||
|
||||
def run_fast_scandir(_dir: str, ext: list):
|
||||
|
@ -237,7 +237,6 @@ class Track:
|
||||
"""
|
||||
|
||||
trackid: str
|
||||
albumid: str
|
||||
title: str
|
||||
artists: str
|
||||
albumartist: str
|
||||
@ -253,7 +252,6 @@ class Track:
|
||||
|
||||
def __init__(self, tags):
|
||||
self.trackid = tags["_id"]["$oid"]
|
||||
self.albumid = tags["albumid"]
|
||||
self.title = tags["title"]
|
||||
self.artists = tags["artists"].split(", ")
|
||||
self.albumartist = tags["albumartist"]
|
||||
@ -263,7 +261,7 @@ class Track:
|
||||
self.length = tags["length"]
|
||||
self.genre = tags["genre"]
|
||||
self.bitrate = tags["bitrate"]
|
||||
self.image = "http://127.0.0.1:8900/images/thumbnails/" + tags["image"]
|
||||
self.image = tags["image"]
|
||||
self.tracknumber = tags["tracknumber"]
|
||||
self.discnumber = tags["discnumber"]
|
||||
|
||||
@ -322,7 +320,6 @@ class Album:
|
||||
Album class
|
||||
"""
|
||||
|
||||
albumid: str
|
||||
album: str
|
||||
artist: str
|
||||
count: int
|
||||
@ -332,11 +329,10 @@ class Album:
|
||||
image: str
|
||||
|
||||
def __init__(self, tags):
|
||||
self.albumid = tags["_id"]["$oid"]
|
||||
self.album = tags["album"]
|
||||
self.artist = tags["artist"]
|
||||
self.count = tags["count"]
|
||||
self.duration = tags["duration"]
|
||||
self.date = tags["date"]
|
||||
self.artistimage = tags["artistimage"]
|
||||
self.image = tags["image"]
|
||||
self.artistimage = "http://127.0.0.1:8900/images/artists/" + tags["artistimage"]
|
||||
self.image = "http://127.0.0.1:8900/images/thumbnails/" + tags["image"]
|
||||
|
26
server/app/searchlib.py
Normal file
26
server/app/searchlib.py
Normal file
@ -0,0 +1,26 @@
|
||||
from typing import List
|
||||
from app import models, trackslib, albumslib, helpers
|
||||
|
||||
TRACKS = trackslib.TRACKS
|
||||
|
||||
|
||||
def get_tracks(query: str) -> List[models.Track]:
|
||||
"""
|
||||
Gets all songs with a given title.
|
||||
"""
|
||||
tracks = [track for track in TRACKS if query.lower() in track.title.lower()]
|
||||
return helpers.remove_duplicates(tracks)
|
||||
|
||||
|
||||
def get_search_albums(query: str) -> List[models.Album]:
|
||||
"""
|
||||
Gets all songs with a given album.
|
||||
"""
|
||||
return albumslib.search_albums_by_name(query)
|
||||
|
||||
|
||||
def get_artists(artist: str) -> List[models.Track]:
|
||||
"""
|
||||
Gets all songs with a given artist.
|
||||
"""
|
||||
return [track for track in TRACKS if artist.lower() in str(track.artists).lower()]
|
@ -1,34 +0,0 @@
|
||||
import os
|
||||
from typing import List
|
||||
from app import models, instances
|
||||
|
||||
|
||||
ALL_MUSIC: List[models.Track] = []
|
||||
|
||||
|
||||
def create_all_tracks() -> List[models.Track]:
|
||||
"""
|
||||
Gets all songs under the ~/ directory.
|
||||
"""
|
||||
print("Getting all songs...")
|
||||
|
||||
tracks: list[models.Track] = []
|
||||
|
||||
for track in instances.songs_instance.get_all_songs():
|
||||
print(track)
|
||||
try:
|
||||
os.chmod(track["filepath"], 0o755)
|
||||
except FileNotFoundError:
|
||||
instances.songs_instance.remove_song_by_filepath(track["filepath"])
|
||||
|
||||
album = instances.album_instance.get_album_by_name(
|
||||
track["album"], track["albumartist"]
|
||||
)
|
||||
|
||||
track["albumid"] = album["_id"]["$oid"]
|
||||
track["image"] = album["image"]
|
||||
|
||||
tracks.append(models.Track(track))
|
||||
|
||||
ALL_MUSIC.clear()
|
||||
ALL_MUSIC.extend(tracks)
|
47
server/app/trackslib.py
Normal file
47
server/app/trackslib.py
Normal file
@ -0,0 +1,47 @@
|
||||
import os
|
||||
from trace import Trace
|
||||
from typing import List
|
||||
from app import models, instances
|
||||
from app import albumslib
|
||||
from app.helpers import remove_duplicates
|
||||
|
||||
|
||||
TRACKS: List[models.Track] = []
|
||||
|
||||
|
||||
def create_all_tracks() -> List[models.Track]:
|
||||
"""
|
||||
Gets all songs under the ~/ directory.
|
||||
"""
|
||||
print("Getting all songs...")
|
||||
tracks: list[models.Track] = []
|
||||
|
||||
for track in instances.songs_instance.get_all_songs():
|
||||
# print(track)
|
||||
# print(albumslib.ALBUMS)
|
||||
try:
|
||||
os.chmod(track["filepath"], 0o755)
|
||||
except FileNotFoundError:
|
||||
instances.songs_instance.remove_song_by_filepath(track["filepath"])
|
||||
|
||||
album = albumslib.find_album(track["album"], track["albumartist"])
|
||||
# print(album)
|
||||
# print(track["album"], track["albumartist"])
|
||||
|
||||
track["image"] = album.image
|
||||
|
||||
tracks.append(models.Track(track))
|
||||
|
||||
TRACKS.clear()
|
||||
TRACKS.extend(tracks)
|
||||
|
||||
|
||||
def get_album_tracks(albumname, artist):
|
||||
"""Returns all tracks matching an album"""
|
||||
_tracks: List[models.Track] = []
|
||||
|
||||
for track in TRACKS:
|
||||
if track.album == albumname and track.albumartist == artist:
|
||||
_tracks.append(track)
|
||||
|
||||
return remove_duplicates(_tracks)
|
@ -3,13 +3,13 @@
|
||||
<div class="a-header">
|
||||
<div
|
||||
class="image art shadow-lg"
|
||||
:style="{ backgroundImage: `url("${encodeURI(props.album_info.image)}")` }"
|
||||
:style="{ backgroundImage: `url("${props.album_info.image}")` }"
|
||||
></div>
|
||||
<div class="info">
|
||||
<div class="top">
|
||||
<div class="h">Album</div>
|
||||
<div class="separator no-border"></div>
|
||||
<div class="title">{{ props.album_info.name }}</div>
|
||||
<div class="title">{{ props.album_info.album }}</div>
|
||||
<div class="artist">{{ props.album_info.artist }}</div>
|
||||
</div>
|
||||
<div class="separator no-border"></div>
|
||||
|
@ -26,6 +26,8 @@
|
||||
:tracks="tracks.tracks"
|
||||
@loadMore="loadMoreTracks"
|
||||
/>
|
||||
<div class="separator no-border"></div>
|
||||
|
||||
<AlbumGrid
|
||||
v-if="albums.albums.length"
|
||||
:albums="albums.albums"
|
||||
|
@ -2,7 +2,7 @@
|
||||
<router-link
|
||||
:to="{
|
||||
name: 'AlbumView',
|
||||
params: { album: album.name, artist: album.artist },
|
||||
params: { album: album.album, artist: album.artist },
|
||||
}"
|
||||
class="result-item shadow-sm"
|
||||
>
|
||||
|
Loading…
x
Reference in New Issue
Block a user