Files
SpotifyRecAlg/swingmusic/start_swingmusic.py
T
Tomas Dvorak 6e8fedf534 first commit
2026-04-13 17:46:58 +02:00

137 lines
4.3 KiB
Python

import mimetypes
import socket
import setproctitle
from swingmusic import app_builder
from swingmusic.crons import start_cron_jobs
from swingmusic.plugins.register import register_plugins
from swingmusic.services.download_jobs import download_job_manager
from swingmusic.services.lyrics_backfill import backfill_library_async
from swingmusic.services.playlist_tracking import playlist_tracking_service
from swingmusic.services.production_readiness import (
ensure_lyrics_defaults,
ensure_owner_and_projection,
)
from swingmusic.services.setup_state import resume_pending_index_if_needed
from swingmusic.setup import load_into_mem, run_setup
from swingmusic.start_info_logger import log_startup_info
from swingmusic.utils.threading import background
def config_mimetypes():
# Load mimetypes for the web client's static files
# Loading mimetypes should happen automaticaly but
# sometimes the mimetypes are not loaded correctly
# eg. when the Registry is messed up on Windows.
# See the following issues:
# https://github.com/swingmx/swingmusic/issues/137
mimetypes.add_type("text/css", ".css")
mimetypes.add_type("text/javascript", ".js")
mimetypes.add_type("text/plain", ".txt")
mimetypes.add_type("text/html", ".html")
mimetypes.add_type("image/webp", ".webp")
mimetypes.add_type("image/svg+xml", ".svg")
mimetypes.add_type("image/png", ".png")
mimetypes.add_type("image/vnd.microsoft.icon", ".ico")
mimetypes.add_type("image/gif", ".gif")
mimetypes.add_type("font/woff", ".woff")
mimetypes.add_type("application/manifest+json", ".webmanifest")
class PortManager:
def __init__(self, host: str):
self.host = host
def test_port(self, port: int):
try:
http_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
http_server.bind((self.host, port))
http_server.close()
return True
except OSError as e:
if e.errno == 48:
return False
else:
raise e
def start_swingmusic(host: str, port: int):
"""
Creates and starts the Flask application server for Swing Music.
This function sets up the Flask application with all necessary
configurations, including static file handling, authentication middleware, and
server setup, then runs it. It also sets up background tasks and cron jobs.
.. note::
The application uses either bjoern or waitress as the WSGI server,
depending on availability. It also includes JWT authentication,
static file serving with gzip compression support, and automatic
token refresh functionality.
:param host: The host address to bind the server to (e.g., 'localhost' or '0.0.0.0')
:param port: The port number to run the server on
"""
# port_manager = PortManager(host)
# Try starting a server on port 1970
# If it fails, exit with error
# if not port_manager.test_port(port):
# print(f"Error 48: Port {port} already in use.")
# print("Please specify a different port using the --port argument.")
# sys.exit(1)
# Example: Setting up dirs, database, and loading stuff into memory.
# TIP: Be careful with the order of the setup functions.
# NOTE: concurrent and multithreading create own sys.modules -> no globals
config_mimetypes()
run_setup()
@background
def run_swingmusic():
register_plugins()
ensure_owner_and_projection()
ensure_lyrics_defaults()
backfill_library_async()
resume_pending_index_if_needed()
setproctitle.setproctitle(f"swingmusic {host}:{port}")
start_cron_jobs()
# Start unified queue worker.
download_job_manager.start()
playlist_tracking_service.start()
print("Download services started")
app = app_builder.build()
log_startup_info(host, port)
load_into_mem()
run_swingmusic()
# TrackStore.export()
# ArtistStore.export()
# docker needs manual flush
print("", end="", flush=True)
try:
import bjoern
bjoern.run(app, host, port)
except ImportError:
import waitress
waitress.serve(
app,
host=host,
port=port,
threads=100,
ipv6=True,
ipv4=True,
)