diff --git a/app/api/__init__.py b/app/api/__init__.py index d9945ae..9aa5dc9 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -17,6 +17,7 @@ from app.api import ( search, send_file, settings, + lyrics ) @@ -43,5 +44,6 @@ def create_api(): app.register_blueprint(imgserver.api) app.register_blueprint(settings.api) app.register_blueprint(colors.api) + app.register_blueprint(lyrics.api) return app diff --git a/app/api/lyrics.py b/app/api/lyrics.py new file mode 100644 index 0000000..5066ff8 --- /dev/null +++ b/app/api/lyrics.py @@ -0,0 +1,25 @@ +from flask import Blueprint, request + +from app.lib.lyrics import get_lyrics + +api = Blueprint("lyrics", __name__, url_prefix="") + + +@api.route("/lyrics", methods=["POST"]) +def send_lyrics(): + """ + Returns the lyrics for a track + """ + data = request.get_json() + + filepath = data.get("filepath", None) + + if filepath is None: + return {"error": "No filepath provided"}, 400 + + lyrics = get_lyrics(filepath) + + if lyrics is None: + return {"error": "No lyrics found"}, 204 + + return {"lyrics": lyrics}, 200 diff --git a/app/lib/lyrics.py b/app/lib/lyrics.py new file mode 100644 index 0000000..6f97c0a --- /dev/null +++ b/app/lib/lyrics.py @@ -0,0 +1,57 @@ +from pathlib import Path + +filepath = "/home/cwilvx/Music/Editor's Pick/Bad Day 😢/6 Dogs - Crying in the Rarri.m4a" + + +def split_line(line: str): + items = line.split("]") + time = items[0].removeprefix("[") + lyric = items[1] if len(items) > 1 else "" + + return (time, lyric.strip()) + + +def convert_to_milliseconds(time: str): + minutes, seconds = time.split(":") + milliseconds = int(minutes) * 60 * 1000 + float(seconds) * 1000 + return int(milliseconds) + + +def get_lyrics_from_lrc(filepath: str): + with open(filepath, mode="r") as file: + lines = (f.removesuffix("\n") for f in file.readlines()) + + lyrics = [] + + for line in lines: + time, lyric = split_line(line) + milliseconds = convert_to_milliseconds(time) + + lyrics.append({milliseconds: lyric}) + + return lyrics + + +def get_lyrics_file_rel_to_track(filepath: str): + """ + Finds the lyrics file relative to the track file + """ + lyrics_path = Path(filepath).with_suffix(".lrc") + + if lyrics_path.exists(): + return lyrics_path + + +def get_lyrics(track_path: str): + """ + Gets the lyrics for a track + """ + lyrics_path = get_lyrics_file_rel_to_track(track_path) + + if lyrics_path: + return get_lyrics_from_lrc(lyrics_path) + else: + return None + + +get_lyrics(filepath)