swingmusic/server/app/lib/playlistlib.py

143 lines
3.6 KiB
Python

"""
This library contains all the functions related to playlists.
"""
import os
import random
import string
from datetime import datetime
from typing import List
from app import exceptions
from app import instances
from app import models
from app import settings
from app.helpers import Get
from app.lib import trackslib
from app.logger import get_logger
from PIL import Image
from PIL import ImageSequence
from werkzeug import datastructures
TrackExistsInPlaylist = exceptions.TrackExistsInPlaylist
logg = get_logger()
def add_track(playlistid: str, trackid: str):
"""
Adds a track to a playlist to the database.
"""
tt = instances.tracks_instance.get_track_by_id(trackid)
if tt is None:
return
track = models.Track(tt)
playlist = instances.playlist_instance.get_playlist_by_id(playlistid)
track = {
"title": track.title,
"artists": tt["artists"],
"album": track.album,
}
if track in playlist["pre_tracks"]:
raise TrackExistsInPlaylist
instances.playlist_instance.add_track_to_playlist(playlistid, track)
def create_thumbnail(image: any, img_path: str) -> str:
"""
Creates a 250 x 250 thumbnail from a playlist image
"""
thumb_path = "thumb_" + img_path
full_thumb_path = os.path.join(settings.APP_DIR, "images", "playlists",
thumb_path)
aspect_ratio = image.width / image.height
new_w = round(250 * aspect_ratio)
thumb = image.resize((new_w, 250), Image.ANTIALIAS)
thumb.save(full_thumb_path, "webp")
return thumb_path
def save_p_image(file: datastructures.FileStorage, pid: str):
"""
Saves the image of a playlist to the database.
"""
img = Image.open(file)
random_str = "".join(
random.choices(string.ascii_letters + string.digits, k=5))
img_path = pid + str(random_str) + ".webp"
full_img_path = os.path.join(settings.APP_DIR, "images", "playlists",
img_path)
if file.content_type == "image/gif":
frames = []
for frame in ImageSequence.Iterator(img):
frames.append(frame.copy())
frames[0].save(full_img_path, save_all=True, append_images=frames[1:])
thumb_path = create_thumbnail(img, img_path=img_path)
return img_path, thumb_path
img.save(full_img_path, "webp")
thumb_path = create_thumbnail(img, img_path=img_path)
return img_path, thumb_path
class ValidatePlaylistThumbs:
"""
Removes all unused images in the images/playlists folder.
"""
def __init__(self) -> None:
images = []
playlists = Get.get_all_playlists()
logg.info("Validating playlist thumbnails")
for playlist in playlists:
if playlist.image:
img_path = playlist.image.split("/")[-1]
thumb_path = playlist.thumb.split("/")[-1]
images.append(img_path)
images.append(thumb_path)
p_path = os.path.join(settings.APP_DIR, "images", "playlists")
for image in os.listdir(p_path):
if image not in images:
os.remove(os.path.join(p_path, image))
logg.info("Validating playlist thumbnails ... ✅")
def create_new_date():
return datetime.now()
def create_playlist_tracks(playlist_tracks: List) -> List[models.Track]:
"""
Creates a list of model.Track objects from a list of playlist track dicts.
"""
tracks: List[models.Track] = []
for t in playlist_tracks:
track = trackslib.get_p_track(t)
if track is not None:
tracks.append(models.Track(track))
return tracks