mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-07-29 07:03:47 +00:00
modularize src
+ merge main.py and manage.py + move start logic to swingmusic/__main__.py + add a run.py on the project root
This commit is contained in:
@@ -107,7 +107,7 @@ jobs:
|
||||
# python -m poetry install
|
||||
- name: Build server
|
||||
run: |
|
||||
python main.py --build
|
||||
python run.py --build
|
||||
env:
|
||||
SWINGMUSIC_APP_VERSION: ${{ inputs.tag }}
|
||||
- name: Rename Unix binary
|
||||
|
||||
+1
-1
@@ -35,4 +35,4 @@ RUN pip install bjoern
|
||||
ARG app_version
|
||||
ENV SWINGMUSIC_APP_VERSION=$app_version
|
||||
|
||||
ENTRYPOINT ["python", "main.py", "--host", "0.0.0.0", "--config", "/config"]
|
||||
ENTRYPOINT ["python", "run.py", "--host", "0.0.0.0", "--config", "/config"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Mungai Njoroge
|
||||
Copyright (c) 2025 Mungai Njoroge
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -122,12 +122,63 @@ services:
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
### Contributing
|
||||
### Contributing and Development
|
||||
|
||||
Swing Music is looking for contributors. If you're interested, please join us at the [Swing Music Community](https://t.me/+9n61PFcgKhozZDE0) group on Telegram. For more information, take a look at https://github.com/swing-opensource/swingmusic/issues/186.
|
||||
|
||||
[**CONTRIBUTING GUIDELINES**](.github/contributing.md).
|
||||
|
||||
> [!TIP]
|
||||
> This project runs on Python 3.11 or newer and uses [uv](https://docs.astral.sh/uv) to manage dependencies. Please [install uv](https://docs.astral.sh/uv/getting-started/installation/) before continuing for an easy setup.
|
||||
|
||||
To set up this project on your computer follow the following steps:
|
||||
|
||||
```sh
|
||||
# 1. Fork the project
|
||||
|
||||
git clone https://github.com/swingmx/swingmusic.git
|
||||
|
||||
# or via SSH
|
||||
|
||||
git clone [email protected]:swingmx/swingmusic.git
|
||||
```
|
||||
|
||||
```sh
|
||||
# 2. Install dependencies
|
||||
|
||||
uv sync
|
||||
```
|
||||
|
||||
```sh
|
||||
# 3. Install wsgi server
|
||||
|
||||
# If you are on Windows, install waitress:
|
||||
uv add waitress
|
||||
|
||||
# If you are on Unix, install bjoern:
|
||||
uv add bjoern
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> The `libev` package is needed on Linux and MacOS. You can install it on other system as shown:
|
||||
>
|
||||
> ```sh
|
||||
> # Arch Linux
|
||||
> pacman -S libev
|
||||
>
|
||||
> # Fedora, CentOS
|
||||
> dnf install libev-devel
|
||||
>
|
||||
> # MacOS
|
||||
> brew install libev
|
||||
> ```
|
||||
|
||||
```sh
|
||||
# 4. Run the program
|
||||
|
||||
uv run python run.py
|
||||
```
|
||||
|
||||
### License
|
||||
|
||||
This software is provided to you with terms stated in the MIT License. Read the full text in the `LICENSE` file located at the root of this repository.
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ cd ../swingmusic
|
||||
# poetry install
|
||||
# Swing gives error if this is not set. Set to version of repo you cloned.
|
||||
export SWINGMUSIC_APP_VERSION="TAG"
|
||||
python main.py --build
|
||||
python run.py --build
|
||||
|
||||
# rename binary
|
||||
mv dist/swingmusic dist/swingmusic_linux_arm64
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
# REVIEW Above: bash is way more compatible than other shells
|
||||
|
||||
# builds the latest version of the client and server
|
||||
|
||||
# REVIEW These are not useful if you dont have the source code
|
||||
#cd ../swingmusic-client
|
||||
#yarn build --outDir ../swingmusic/client
|
||||
#../swingmusic
|
||||
|
||||
# REVIEW Cleaning up
|
||||
rm -rf build dist
|
||||
|
||||
# REVIEW Install poetry & requirements
|
||||
poetry || pip install poetry
|
||||
poetry install --no-root
|
||||
|
||||
# Build the app
|
||||
poetry run python manage.py --build
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
# REVIEW Above: bash is way more compatible than other shells
|
||||
|
||||
# builds the latest version of the client and server
|
||||
|
||||
# NOTE Changes directory to the webclient directory and builds it
|
||||
cd ../swingmusic-client || exit # REVIEW Failsafe exit
|
||||
yarn build --outDir ../swingmusic/client
|
||||
cd ../swingmusic || exit # REVIEW Failsafe exit
|
||||
|
||||
# REVIEW Optional cleaning up
|
||||
# rm -rf build dist
|
||||
|
||||
# REVIEW Install poetry & requirements
|
||||
# Build the app
|
||||
poetry run python manage.py --build
|
||||
@@ -1,80 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import click
|
||||
import pathlib
|
||||
import multiprocessing
|
||||
from app.arg_handler import handle_build, handle_password_reset
|
||||
from app.utils.filesystem import get_home_res_path
|
||||
from app.utils.xdg_utils import get_xdg_config_dir
|
||||
from manage import create_app
|
||||
|
||||
|
||||
def version(*args, **kwargs):
|
||||
if not args[2]:
|
||||
return
|
||||
|
||||
path = get_home_res_path("version.txt")
|
||||
if not path:
|
||||
click.echo("Version file not found.")
|
||||
sys.exit(1)
|
||||
|
||||
with open(path, "r") as f:
|
||||
version = f.read()
|
||||
|
||||
click.echo(version)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@click.command(options_metavar="<options>", context_settings={"show_default": True})
|
||||
@click.option(
|
||||
"--build",
|
||||
default=False,
|
||||
help="Build the project.",
|
||||
is_eager=True,
|
||||
callback=handle_build,
|
||||
is_flag=True,
|
||||
)
|
||||
@click.option("--host", default="0.0.0.0", help="Host to run the app on.")
|
||||
@click.option("--port", default=1970, help="HTTP port to run the app on.")
|
||||
@click.option(
|
||||
"--config",
|
||||
default=lambda: get_xdg_config_dir(),
|
||||
show_default="XDG_CONFIG_HOME",
|
||||
help="Path to the config file.",
|
||||
type=click.Path(
|
||||
exists=True,
|
||||
file_okay=False,
|
||||
dir_okay=True,
|
||||
writable=True,
|
||||
resolve_path=True,
|
||||
allow_dash=False,
|
||||
path_type=pathlib.Path,
|
||||
),
|
||||
)
|
||||
@click.option(
|
||||
"--password-reset",
|
||||
is_flag=True,
|
||||
help="Reset the password.",
|
||||
is_eager=True,
|
||||
callback=handle_password_reset,
|
||||
)
|
||||
@click.option(
|
||||
"--version",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
callback=version,
|
||||
help="Show the version and exit",
|
||||
is_eager=True,
|
||||
)
|
||||
def run(*args, **kwargs):
|
||||
# INFO: Set the config dir as an environment variable
|
||||
os.environ["SWINGMUSIC_XDG_CONFIG_DIR"] = str(
|
||||
pathlib.Path(kwargs["config"]).resolve()
|
||||
)
|
||||
create_app(kwargs["host"], kwargs["port"], kwargs["config"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
multiprocessing.freeze_support()
|
||||
multiprocessing.set_start_method("spawn")
|
||||
run()
|
||||
+1
-2
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "swingmusic"
|
||||
version = "2.0.2"
|
||||
version = "2.0.6"
|
||||
description = "Swing Music"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11, <3.12"
|
||||
@@ -31,7 +31,6 @@ dependencies = [
|
||||
"pillow>=11.1.0",
|
||||
"flask-openapi3==3.0.2",
|
||||
"rapidfuzz==3.11.0",
|
||||
"waitress>=3.0.2",
|
||||
"pendulum>=3.0.0",
|
||||
"bjoern>=3.2.2",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# Launcher script
|
||||
|
||||
import multiprocessing
|
||||
import swingmusic.__main__ as app
|
||||
|
||||
if __name__ == "__main__":
|
||||
multiprocessing.freeze_support()
|
||||
multiprocessing.set_start_method("spawn")
|
||||
app.run()
|
||||
@@ -1,12 +1,12 @@
|
||||
"""
|
||||
This file is used to run the application.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import click
|
||||
import pathlib
|
||||
import logging
|
||||
import mimetypes
|
||||
import setproctitle
|
||||
from pathlib import Path
|
||||
import multiprocessing
|
||||
|
||||
|
||||
from flask_jwt_extended import (
|
||||
create_access_token,
|
||||
@@ -18,19 +18,58 @@ from flask_jwt_extended import (
|
||||
from datetime import datetime, timezone
|
||||
from flask import Response, request
|
||||
|
||||
from app import settings
|
||||
from app.api import create_api
|
||||
from app.crons import start_cron_jobs
|
||||
from app.utils.threading import background
|
||||
from app.setup import load_into_mem, run_setup
|
||||
from app.plugins.register import register_plugins
|
||||
from app.start_info_logger import log_startup_info
|
||||
from app.utils.filesystem import get_home_res_path
|
||||
from app.utils.paths import getClientFilesExtensions
|
||||
from swingmusic import settings
|
||||
from swingmusic.api import create_api
|
||||
from swingmusic.crons import start_cron_jobs
|
||||
from swingmusic.utils.threading import background
|
||||
from swingmusic.setup import load_into_mem, run_setup
|
||||
from swingmusic.plugins.register import register_plugins
|
||||
from swingmusic.utils.xdg_utils import get_xdg_config_dir
|
||||
from swingmusic.start_info_logger import log_startup_info
|
||||
from swingmusic.utils.filesystem import get_home_res_path
|
||||
from swingmusic.utils.paths import getClientFilesExtensions
|
||||
from swingmusic.arg_handler import handle_build, handle_password_reset
|
||||
|
||||
def print_version(*args, **kwargs):
|
||||
"""
|
||||
Prints the version of the application.
|
||||
"""
|
||||
if not args[2]:
|
||||
return
|
||||
|
||||
path = get_home_res_path("version.txt")
|
||||
if not path:
|
||||
click.echo("Version file not found.")
|
||||
sys.exit(1)
|
||||
|
||||
with open(path, "r") as f:
|
||||
version = f.read()
|
||||
|
||||
click.echo(version)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def create_app(host: str, port: int, config: Path):
|
||||
# settings.Paths.set_config_dir(config)
|
||||
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.
|
||||
|
||||
Args:
|
||||
host (str): The host address to bind the server to (e.g., 'localhost' or '0.0.0.0')
|
||||
port (int): The port number to run the server on
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
# Example: Setting up dirs, database, and loading stuff into memory.
|
||||
# TIP: Be careful with the order of the setup functions.
|
||||
|
||||
# Load mimetypes for the web client's static files
|
||||
# Loading mimetypes should happen automatically but
|
||||
@@ -196,3 +235,62 @@ def create_app(host: str, port: int, config: Path):
|
||||
ipv6=True,
|
||||
ipv4=True,
|
||||
)
|
||||
|
||||
|
||||
@click.command(options_metavar="<options>", context_settings={"show_default": True})
|
||||
@click.option(
|
||||
"--build",
|
||||
default=False,
|
||||
help="Build the project.",
|
||||
is_eager=True,
|
||||
callback=handle_build,
|
||||
is_flag=True,
|
||||
)
|
||||
@click.option("--host", default="0.0.0.0", help="Host to run the app on.")
|
||||
@click.option("--port", default=1970, help="HTTP port to run the app on.")
|
||||
@click.option(
|
||||
"--config",
|
||||
default=lambda: get_xdg_config_dir(),
|
||||
show_default="XDG_CONFIG_HOME",
|
||||
help="Path to the config file.",
|
||||
type=click.Path(
|
||||
exists=True,
|
||||
file_okay=False,
|
||||
dir_okay=True,
|
||||
writable=True,
|
||||
resolve_path=True,
|
||||
allow_dash=False,
|
||||
path_type=pathlib.Path,
|
||||
),
|
||||
)
|
||||
@click.option(
|
||||
"--password-reset",
|
||||
is_flag=True,
|
||||
help="Reset the password.",
|
||||
is_eager=True,
|
||||
callback=handle_password_reset,
|
||||
)
|
||||
@click.option(
|
||||
"--version",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
callback=print_version,
|
||||
help="Show the version and exit",
|
||||
is_eager=True,
|
||||
)
|
||||
def run(*args, **kwargs):
|
||||
"""
|
||||
Swing Music entry point. All commandline arguments are handled
|
||||
here by the click decorators and configuration.
|
||||
"""
|
||||
# INFO: Set the config dir as an environment variable
|
||||
os.environ["SWINGMUSIC_XDG_CONFIG_DIR"] = str(
|
||||
pathlib.Path(kwargs["config"]).resolve()
|
||||
)
|
||||
start_swingmusic(kwargs["host"], kwargs["port"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
multiprocessing.freeze_support()
|
||||
multiprocessing.set_start_method("spawn")
|
||||
run()
|
||||
@@ -9,13 +9,13 @@ from flask_compress import Compress
|
||||
from flask_openapi3 import Info
|
||||
from flask_openapi3 import OpenAPI
|
||||
from flask_jwt_extended import JWTManager
|
||||
from app.config import UserConfig
|
||||
from swingmusic.config import UserConfig
|
||||
|
||||
from app.db.userdata import UserTable
|
||||
from app.settings import Info as AppInfo
|
||||
from swingmusic.db.userdata import UserTable
|
||||
from swingmusic.settings import Info as AppInfo
|
||||
from .plugins import lyrics as lyrics_plugin
|
||||
from .plugins import mixes as mixes_plugin
|
||||
from app.api import (
|
||||
from swingmusic.api import (
|
||||
album,
|
||||
artist,
|
||||
collections,
|
||||
@@ -9,20 +9,20 @@ import random
|
||||
from pydantic import BaseModel, Field
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from app.api.apischemas import AlbumHashSchema, AlbumLimitSchema, ArtistHashSchema
|
||||
from swingmusic.api.apischemas import AlbumHashSchema, AlbumLimitSchema, ArtistHashSchema
|
||||
|
||||
from app.config import UserConfig
|
||||
from app.db.userdata import SimilarArtistTable
|
||||
from app.models.album import Album
|
||||
from app.settings import Defaults
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.hashing import create_hash
|
||||
from app.lib.albumslib import sort_by_track_no
|
||||
from app.serializers.album import serialize_for_card_many
|
||||
from app.serializers.track import serialize_tracks
|
||||
from app.utils.stats import get_track_group_stats
|
||||
from swingmusic.config import UserConfig
|
||||
from swingmusic.db.userdata import SimilarArtistTable
|
||||
from swingmusic.models.album import Album
|
||||
from swingmusic.settings import Defaults
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.hashing import create_hash
|
||||
from swingmusic.lib.albumslib import sort_by_track_no
|
||||
from swingmusic.serializers.album import serialize_for_card_many
|
||||
from swingmusic.serializers.track import serialize_tracks
|
||||
from swingmusic.utils.stats import get_track_group_stats
|
||||
|
||||
|
||||
bp_tag = Tag(name="Album", description="Single album")
|
||||
@@ -4,7 +4,7 @@ Reusable Pydantic basic schemas for the API
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.settings import Defaults
|
||||
from swingmusic.settings import Defaults
|
||||
|
||||
|
||||
class AlbumHashSchema(BaseModel):
|
||||
@@ -11,25 +11,25 @@ from typing import Any
|
||||
|
||||
from flask_openapi3 import APIBlueprint, Tag
|
||||
from pydantic import Field
|
||||
from app.api.apischemas import (
|
||||
from swingmusic.api.apischemas import (
|
||||
AlbumLimitSchema,
|
||||
ArtistHashSchema,
|
||||
ArtistLimitSchema,
|
||||
TrackLimitSchema,
|
||||
)
|
||||
|
||||
from app.config import UserConfig
|
||||
from app.db.userdata import SimilarArtistTable
|
||||
from app.lib.sortlib import sort_tracks
|
||||
from swingmusic.config import UserConfig
|
||||
from swingmusic.db.userdata import SimilarArtistTable
|
||||
from swingmusic.lib.sortlib import sort_tracks
|
||||
|
||||
from app.serializers.album import serialize_for_card_many
|
||||
from app.serializers.artist import serialize_for_cards, serialize_for_card
|
||||
from app.serializers.track import serialize_track
|
||||
from swingmusic.serializers.album import serialize_for_card_many
|
||||
from swingmusic.serializers.artist import serialize_for_cards, serialize_for_card
|
||||
from swingmusic.serializers.track import serialize_track
|
||||
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.stats import get_track_group_stats
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.stats import get_track_group_stats
|
||||
|
||||
bp_tag = Tag(name="Artist", description="Single artist")
|
||||
api = APIBlueprint("artist", __name__, url_prefix="/artist", abp_tags=[bp_tag])
|
||||
@@ -14,9 +14,9 @@ from pydantic import BaseModel, Field
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
|
||||
from app.db.userdata import UserTable
|
||||
from app.utils.auth import check_password, hash_password
|
||||
from app.config import UserConfig
|
||||
from swingmusic.db.userdata import UserTable
|
||||
from swingmusic.utils.auth import check_password, hash_password
|
||||
from swingmusic.config import UserConfig
|
||||
|
||||
bp_tag = Tag(name="Auth", description="Authentication stuff")
|
||||
api = APIBlueprint("auth", __name__, url_prefix="/auth", abp_tags=[bp_tag])
|
||||
@@ -7,13 +7,13 @@ import shutil
|
||||
from time import time
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from app.api.auth import admin_required
|
||||
from swingmusic.api.auth import admin_required
|
||||
|
||||
from app.db.userdata import FavoritesTable, PlaylistTable, ScrobbleTable
|
||||
from app.lib.index import index_everything
|
||||
from app.settings import Paths
|
||||
from swingmusic.db.userdata import FavoritesTable, PlaylistTable, ScrobbleTable
|
||||
from swingmusic.lib.index import index_everything
|
||||
from swingmusic.settings import Paths
|
||||
from datetime import datetime
|
||||
from app.utils.dates import timestamp_to_time_passed
|
||||
from swingmusic.utils.dates import timestamp_to_time_passed
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
@@ -8,9 +8,9 @@ from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.db.userdata import CollectionTable
|
||||
from app.lib.pagelib import recover_page_items, remove_page_items, validate_page_items
|
||||
from app.utils.auth import get_current_userid
|
||||
from swingmusic.db.userdata import CollectionTable
|
||||
from swingmusic.lib.pagelib import recover_page_items, remove_page_items, validate_page_items
|
||||
from swingmusic.utils.auth import get_current_userid
|
||||
|
||||
bp_tag = Tag(name="Collections", description="Collections")
|
||||
api = APIBlueprint(
|
||||
@@ -1,7 +1,7 @@
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from app.api.apischemas import AlbumHashSchema
|
||||
from app.store.albums import AlbumStore as Store
|
||||
from swingmusic.api.apischemas import AlbumHashSchema
|
||||
from swingmusic.store.albums import AlbumStore as Store
|
||||
|
||||
bp_tag = Tag(name="Colors", description="Get item colors")
|
||||
api = APIBlueprint("colors", __name__, url_prefix="/colors", abp_tags=[bp_tag])
|
||||
@@ -4,23 +4,23 @@ from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.api.apischemas import GenericLimitSchema
|
||||
from app.db.userdata import FavoritesTable
|
||||
from app.lib.extras import get_extra_info
|
||||
from app.models import FavType
|
||||
from app.settings import Defaults
|
||||
from swingmusic.api.apischemas import GenericLimitSchema
|
||||
from swingmusic.db.userdata import FavoritesTable
|
||||
from swingmusic.lib.extras import get_extra_info
|
||||
from swingmusic.models import FavType
|
||||
from swingmusic.settings import Defaults
|
||||
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
from app.serializers.track import serialize_track, serialize_tracks
|
||||
from app.serializers.artist import (
|
||||
from swingmusic.serializers.track import serialize_track, serialize_tracks
|
||||
from swingmusic.serializers.artist import (
|
||||
serialize_for_card as serialize_artist,
|
||||
serialize_for_cards,
|
||||
)
|
||||
from app.utils.dates import timestamp_to_time_passed
|
||||
from app.serializers.album import serialize_for_card, serialize_for_card_many
|
||||
from swingmusic.utils.dates import timestamp_to_time_passed
|
||||
from swingmusic.serializers.album import serialize_for_card, serialize_for_card_many
|
||||
|
||||
bp_tag = Tag(name="Favorites", description="Your favorite items")
|
||||
api = APIBlueprint("favorites", __name__, url_prefix="/favorites", abp_tags=[bp_tag])
|
||||
@@ -12,14 +12,14 @@ from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from showinfm import show_in_file_manager
|
||||
|
||||
from app import settings
|
||||
from app.config import UserConfig
|
||||
from app.db.libdata import TrackTable
|
||||
from app.db.userdata import FavoritesTable, PlaylistTable
|
||||
from app.lib.folderslib import get_files_and_dirs, get_folders
|
||||
from app.serializers.track import serialize_track, serialize_tracks
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.wintools import is_windows, win_replace_slash
|
||||
from swingmusic import settings
|
||||
from swingmusic.config import UserConfig
|
||||
from swingmusic.db.libdata import TrackTable
|
||||
from swingmusic.db.userdata import FavoritesTable, PlaylistTable
|
||||
from swingmusic.lib.folderslib import get_files_and_dirs, get_folders
|
||||
from swingmusic.serializers.track import serialize_track, serialize_tracks
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.wintools import is_windows, win_replace_slash
|
||||
|
||||
tag = Tag(name="Folders", description="Get folders and tracks in a directory")
|
||||
api = APIBlueprint("folder", __name__, url_prefix="/folder", abp_tags=[tag])
|
||||
@@ -3,14 +3,14 @@ from flask_openapi3 import APIBlueprint
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from datetime import datetime
|
||||
from app.api.apischemas import GenericLimitSchema
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from swingmusic.api.apischemas import GenericLimitSchema
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
|
||||
from app.serializers.album import serialize_for_card as serialize_album
|
||||
from app.serializers.artist import serialize_for_card as serialize_artist
|
||||
from app.utils import format_number
|
||||
from app.utils.dates import (
|
||||
from swingmusic.serializers.album import serialize_for_card as serialize_album
|
||||
from swingmusic.serializers.artist import serialize_for_card as serialize_artist
|
||||
from swingmusic.utils import format_number
|
||||
from swingmusic.utils.dates import (
|
||||
create_new_date,
|
||||
date_string_to_time_passed,
|
||||
seconds_to_time_string,
|
||||
@@ -2,10 +2,10 @@ from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.api.apischemas import GenericLimitSchema
|
||||
from app.lib.home.recentlyadded import get_recently_added_items
|
||||
from app.lib.home.get_recently_played import get_recently_played
|
||||
from app.store.homepage import HomepageStore
|
||||
from swingmusic.api.apischemas import GenericLimitSchema
|
||||
from swingmusic.lib.home.recentlyadded import get_recently_added_items
|
||||
from swingmusic.lib.home.get_recently_played import get_recently_played
|
||||
from swingmusic.store.homepage import HomepageStore
|
||||
|
||||
bp_tag = Tag(name="Home", description="Homepage items")
|
||||
api = APIBlueprint("home", __name__, url_prefix="/nothome", abp_tags=[bp_tag])
|
||||
@@ -5,10 +5,10 @@ from flask_openapi3 import APIBlueprint
|
||||
from pydantic import BaseModel, Field
|
||||
from flask import send_from_directory
|
||||
|
||||
from app.settings import Defaults, Paths
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.threading import background
|
||||
from swingmusic.settings import Defaults, Paths
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.threading import background
|
||||
from PIL import Image
|
||||
|
||||
bp_tag = Tag(
|
||||
@@ -2,8 +2,8 @@ from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from pydantic import Field
|
||||
|
||||
from app.api.apischemas import TrackHashSchema
|
||||
from app.lib.lyrics import (
|
||||
from swingmusic.api.apischemas import TrackHashSchema
|
||||
from swingmusic.lib.lyrics import (
|
||||
get_lyrics,
|
||||
check_lyrics_file,
|
||||
get_lyrics_from_duplicates,
|
||||
@@ -14,21 +14,21 @@ from pydantic import BaseModel, Field, GetCoreSchemaHandler
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint, FileStorage as _FileStorage
|
||||
|
||||
from app import models
|
||||
from app.api.apischemas import GenericLimitSchema
|
||||
from app.db.userdata import PlaylistTable
|
||||
from app.lib import playlistlib
|
||||
from app.lib.albumslib import sort_by_track_no
|
||||
from app.lib.home.recentlyadded import get_recently_added_playlist
|
||||
from app.lib.home.recentlyplayed import get_recently_played_playlist
|
||||
from app.lib.sortlib import sort_tracks
|
||||
from app.models.playlist import Playlist
|
||||
from app.serializers.playlist import serialize_for_card
|
||||
from app.serializers.track import serialize_tracks
|
||||
from swingmusic import models
|
||||
from swingmusic.api.apischemas import GenericLimitSchema
|
||||
from swingmusic.db.userdata import PlaylistTable
|
||||
from swingmusic.lib import playlistlib
|
||||
from swingmusic.lib.albumslib import sort_by_track_no
|
||||
from swingmusic.lib.home.recentlyadded import get_recently_added_playlist
|
||||
from swingmusic.lib.home.recentlyplayed import get_recently_played_playlist
|
||||
from swingmusic.lib.sortlib import sort_tracks
|
||||
from swingmusic.models.playlist import Playlist
|
||||
from swingmusic.serializers.playlist import serialize_for_card
|
||||
from swingmusic.serializers.track import serialize_tracks
|
||||
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.dates import create_new_date, date_string_to_time_passed
|
||||
from app.settings import Paths
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.dates import create_new_date, date_string_to_time_passed
|
||||
from swingmusic.settings import Paths
|
||||
|
||||
tag = Tag(name="Playlists", description="Get and manage playlists")
|
||||
api = APIBlueprint("playlists", __name__, url_prefix="/playlists", abp_tags=[tag])
|
||||
@@ -1,11 +1,11 @@
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from pydantic import BaseModel, Field
|
||||
from app.api.auth import admin_required
|
||||
from app.config import UserConfig
|
||||
from app.db.userdata import PluginTable
|
||||
from app.plugins.lastfm import LastFmPlugin
|
||||
from app.utils.auth import get_current_userid
|
||||
from swingmusic.api.auth import admin_required
|
||||
from swingmusic.config import UserConfig
|
||||
from swingmusic.db.userdata import PluginTable
|
||||
from swingmusic.plugins.lastfm import LastFmPlugin
|
||||
from swingmusic.utils.auth import get_current_userid
|
||||
|
||||
bp_tag = Tag(name="Plugins", description="Manage plugins")
|
||||
api = APIBlueprint("plugins", __name__, url_prefix="/plugins", abp_tags=[bp_tag])
|
||||
@@ -1,12 +1,12 @@
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from pydantic import Field
|
||||
from app.api.apischemas import TrackHashSchema
|
||||
from app.lib.lyrics import format_synced_lyrics
|
||||
from swingmusic.api.apischemas import TrackHashSchema
|
||||
from swingmusic.lib.lyrics import format_synced_lyrics
|
||||
|
||||
from app.plugins.lyrics import Lyrics
|
||||
from app.settings import Defaults
|
||||
from app.utils.hashing import create_hash
|
||||
from swingmusic.plugins.lyrics import Lyrics
|
||||
from swingmusic.settings import Defaults
|
||||
from swingmusic.utils.hashing import create_hash
|
||||
|
||||
bp_tag = Tag(name="Lyrics Plugin", description="Musixmatch lyrics plugin")
|
||||
api = APIBlueprint(
|
||||
@@ -3,10 +3,10 @@ from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.db.userdata import MixTable
|
||||
from app.plugins.mixes import MixesPlugin
|
||||
from app.store.homepage import HomepageStore
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic.db.userdata import MixTable
|
||||
from swingmusic.plugins.mixes import MixesPlugin
|
||||
from swingmusic.store.homepage import HomepageStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
|
||||
bp_tag = Tag(name="Mixes Plugin", description="Mixes plugin hehe")
|
||||
@@ -3,30 +3,30 @@ from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
import pendulum
|
||||
from pydantic import Field, BaseModel
|
||||
from app.api.apischemas import TrackHashSchema
|
||||
from swingmusic.api.apischemas import TrackHashSchema
|
||||
from typing import Literal
|
||||
import locale
|
||||
|
||||
from app.db.userdata import FavoritesTable, ScrobbleTable
|
||||
from app.lib.extras import get_extra_info
|
||||
from app.lib.recipes.recents import RecentlyPlayed
|
||||
from app.models.album import Album
|
||||
from app.models.stats import StatItem
|
||||
from app.models.track import Track
|
||||
from app.plugins.lastfm import LastFmPlugin
|
||||
from app.serializers.artist import serialize_for_card
|
||||
from app.serializers.album import serialize_for_card as serialize_for_album_card
|
||||
from app.serializers.track import serialize_track, serialize_tracks
|
||||
from app.settings import Defaults
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.dates import (
|
||||
from swingmusic.db.userdata import FavoritesTable, ScrobbleTable
|
||||
from swingmusic.lib.extras import get_extra_info
|
||||
from swingmusic.lib.recipes.recents import RecentlyPlayed
|
||||
from swingmusic.models.album import Album
|
||||
from swingmusic.models.stats import StatItem
|
||||
from swingmusic.models.track import Track
|
||||
from swingmusic.plugins.lastfm import LastFmPlugin
|
||||
from swingmusic.serializers.artist import serialize_for_card
|
||||
from swingmusic.serializers.album import serialize_for_card as serialize_for_album_card
|
||||
from swingmusic.serializers.track import serialize_track, serialize_tracks
|
||||
from swingmusic.settings import Defaults
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.dates import (
|
||||
get_date_range,
|
||||
get_duration_in_seconds,
|
||||
seconds_to_time_string,
|
||||
)
|
||||
from app.utils.stats import (
|
||||
from swingmusic.utils.stats import (
|
||||
calculate_album_trend,
|
||||
calculate_artist_trend,
|
||||
calculate_new_albums,
|
||||
@@ -8,12 +8,12 @@ from pydantic import Field
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
|
||||
from app import models
|
||||
from app.api.apischemas import GenericLimitSchema
|
||||
from app.lib import searchlib
|
||||
from app.serializers.artist import serialize_for_cards
|
||||
from app.settings import Defaults
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic import models
|
||||
from swingmusic.api.apischemas import GenericLimitSchema
|
||||
from swingmusic.lib import searchlib
|
||||
from swingmusic.serializers.artist import serialize_for_cards
|
||||
from swingmusic.settings import Defaults
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
|
||||
tag = Tag(name="Search", description="Search for tracks, albums and artists")
|
||||
@@ -3,13 +3,13 @@ from typing import Any
|
||||
from flask_openapi3 import Tag
|
||||
from flask_openapi3 import APIBlueprint
|
||||
from pydantic import BaseModel, Field
|
||||
from app.api.auth import admin_required
|
||||
from swingmusic.api.auth import admin_required
|
||||
|
||||
from app.db.userdata import PluginTable
|
||||
from app.lib.index import index_everything
|
||||
from app.settings import Info
|
||||
from app.config import UserConfig
|
||||
from app.utils.auth import get_current_userid
|
||||
from swingmusic.db.userdata import PluginTable
|
||||
from swingmusic.lib.index import index_everything
|
||||
from swingmusic.settings import Info
|
||||
from swingmusic.config import UserConfig
|
||||
from swingmusic.utils.auth import get_current_userid
|
||||
|
||||
bp_tag = Tag(name="Settings", description="Customize stuff")
|
||||
api = APIBlueprint("settings", __name__, url_prefix="/notsettings", abp_tags=[bp_tag])
|
||||
@@ -12,12 +12,12 @@ from flask import send_file, request, Response, send_from_directory
|
||||
from flask_openapi3 import APIBlueprint, Tag
|
||||
from pydantic import BaseModel, Field
|
||||
import werkzeug.wsgi
|
||||
from app.api.apischemas import TrackHashSchema
|
||||
from app.lib.trackslib import get_silence_paddings
|
||||
from app.lib.transcoder import start_transcoding
|
||||
from swingmusic.api.apischemas import TrackHashSchema
|
||||
from swingmusic.lib.trackslib import get_silence_paddings
|
||||
from swingmusic.lib.transcoder import start_transcoding
|
||||
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.files import guess_mime_type
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.files import guess_mime_type
|
||||
|
||||
bp_tag = Tag(name="File", description="Audio files")
|
||||
api = APIBlueprint("track", __name__, url_prefix="/file", abp_tags=[bp_tag])
|
||||
@@ -8,13 +8,13 @@ from getpass import getpass
|
||||
import click
|
||||
import PyInstaller.__main__ as bundler
|
||||
|
||||
from app import settings
|
||||
from app.db.userdata import UserTable
|
||||
from app.logger import log
|
||||
from app.setup.sqlite import setup_sqlite
|
||||
from app.utils.auth import hash_password
|
||||
from app.utils.paths import getFlaskOpenApiPath
|
||||
from app.utils.wintools import is_windows
|
||||
from swingmusic import settings
|
||||
from swingmusic.db.userdata import UserTable
|
||||
from swingmusic.logger import log
|
||||
from swingmusic.setup.sqlite import setup_sqlite
|
||||
from swingmusic.utils.auth import hash_password
|
||||
from swingmusic.utils.paths import getFlaskOpenApiPath
|
||||
from swingmusic.utils.wintools import is_windows
|
||||
|
||||
ALLARGS = settings.ALLARGS
|
||||
ARGS = sys.argv[1:]
|
||||
@@ -52,7 +52,7 @@ def handle_build(*args, **kwargs):
|
||||
|
||||
try:
|
||||
# write the info to the config file
|
||||
with open("./app/configs.py", "w", encoding="utf-8") as file:
|
||||
with open("./swingmusic/configs.py", "w", encoding="utf-8") as file:
|
||||
# copy the api keys to the config file
|
||||
file.writelines(lines)
|
||||
|
||||
@@ -63,7 +63,7 @@ def handle_build(*args, **kwargs):
|
||||
|
||||
bundler.run(
|
||||
[
|
||||
"main.py",
|
||||
"run.py",
|
||||
"--onefile",
|
||||
"--name",
|
||||
"swingmusic",
|
||||
@@ -73,13 +73,17 @@ def handle_build(*args, **kwargs):
|
||||
f"--add-data=version.txt{_s}.",
|
||||
f"--add-data={flask_openapi_path}/templates/static{_s}flask_openapi3/templates/static",
|
||||
f"--hidden-import={server_module}",
|
||||
"--collect-submodules=swingmusic",
|
||||
"--icon=assets/logo-fill.light.ico",
|
||||
"-y",
|
||||
]
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error building the project: {e}")
|
||||
sys.exit(0)
|
||||
finally:
|
||||
# revert and remove the api keys for dev mode
|
||||
with open("./app/configs.py", "w", encoding="utf-8") as file:
|
||||
with open("./swingmusic/configs.py", "w", encoding="utf-8") as file:
|
||||
lines = [f'{key} = ""\n' for key in info_keys]
|
||||
file.writelines(lines)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import time
|
||||
import schedule
|
||||
|
||||
from app.crons.mixes import Mixes
|
||||
from app.lib.recipes.recents import RecentlyAdded, RecentlyPlayed
|
||||
from app.lib.recipes.topstreamed import TopArtists
|
||||
from app.utils.threading import background
|
||||
from swingmusic.crons.mixes import Mixes
|
||||
from swingmusic.lib.recipes.recents import RecentlyAdded, RecentlyPlayed
|
||||
from swingmusic.lib.recipes.topstreamed import TopArtists
|
||||
from swingmusic.utils.threading import background
|
||||
|
||||
|
||||
@background
|
||||
@@ -1,6 +1,6 @@
|
||||
from app.crons.cron import CronJob
|
||||
from app.lib.recipes.artistmixes import ArtistMixes
|
||||
from app.lib.recipes.because import BecauseYouListened
|
||||
from swingmusic.crons.cron import CronJob
|
||||
from swingmusic.lib.recipes.artistmixes import ArtistMixes
|
||||
from swingmusic.lib.recipes.because import BecauseYouListened
|
||||
|
||||
|
||||
class Mixes(CronJob):
|
||||
@@ -8,7 +8,7 @@ from sqlalchemy import (
|
||||
)
|
||||
|
||||
from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass
|
||||
from app.db.engine import DbEngine
|
||||
from swingmusic.db.engine import DbEngine
|
||||
|
||||
|
||||
class Base(MappedAsDataclass, DeclarativeBase):
|
||||
@@ -2,7 +2,7 @@ from contextlib import contextmanager
|
||||
from sqlalchemy import Engine, create_engine, event
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from app.settings import DbPaths
|
||||
from swingmusic.settings import DbPaths
|
||||
|
||||
|
||||
@event.listens_for(Engine, "connect")
|
||||
@@ -1,7 +1,7 @@
|
||||
from app.config import UserConfig
|
||||
from app.db import Base
|
||||
from app.db.utils import track_to_dataclass, tracks_to_dataclasses
|
||||
from app.db.engine import DbEngine
|
||||
from swingmusic.config import UserConfig
|
||||
from swingmusic.db import Base
|
||||
from swingmusic.db.utils import track_to_dataclass, tracks_to_dataclasses
|
||||
from swingmusic.db.engine import DbEngine
|
||||
from sqlalchemy import JSON, Integer, String, delete, select
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from app.db import Base
|
||||
from swingmusic.db import Base
|
||||
|
||||
|
||||
from sqlalchemy import Integer, insert, select, update
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from app.db.engine import DbEngine
|
||||
from swingmusic.db.engine import DbEngine
|
||||
|
||||
|
||||
class MigrationTable(Base):
|
||||
@@ -2,7 +2,7 @@
|
||||
Reads and saves the latest database migrations version.
|
||||
"""
|
||||
|
||||
from app.db.sqlite.utils import SQLiteManager
|
||||
from swingmusic.db.sqlite.utils import SQLiteManager
|
||||
|
||||
|
||||
class MigrationManager:
|
||||
@@ -7,8 +7,8 @@ from sqlite3 import Connection, Cursor
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
from app.models import Album, Playlist, Track
|
||||
from app import settings
|
||||
from swingmusic.models import Album, Playlist, Track
|
||||
from swingmusic import settings
|
||||
|
||||
|
||||
def tuple_to_track(track: tuple):
|
||||
@@ -17,8 +17,8 @@ from sqlalchemy import (
|
||||
|
||||
from sqlalchemy.orm import Mapped, mapped_column, sessionmaker
|
||||
|
||||
from app.db.engine import DbEngine
|
||||
from app.db.utils import (
|
||||
from swingmusic.db.engine import DbEngine
|
||||
from swingmusic.db.utils import (
|
||||
favorite_to_dataclass,
|
||||
favorites_to_dataclass,
|
||||
playlist_to_dataclass,
|
||||
@@ -28,9 +28,9 @@ from app.db.utils import (
|
||||
user_to_dataclass,
|
||||
)
|
||||
|
||||
from app.db import Base
|
||||
from app.models.mix import Mix
|
||||
from app.utils.auth import get_current_userid, hash_password
|
||||
from swingmusic.db import Base
|
||||
from swingmusic.models.mix import Mix
|
||||
from swingmusic.utils.auth import get_current_userid, hash_password
|
||||
|
||||
|
||||
class UserTable(Base):
|
||||
@@ -1,13 +1,13 @@
|
||||
from typing import Any
|
||||
|
||||
from app.config import UserConfig
|
||||
from app.models import Album as AlbumModel, Artist as ArtistModel, Track as TrackModel
|
||||
from app.models.favorite import Favorite
|
||||
from app.models.lastfm import SimilarArtist
|
||||
from app.models.logger import TrackLog
|
||||
from app.models.playlist import Playlist
|
||||
from app.models.plugins import Plugin
|
||||
from app.models.user import User
|
||||
from swingmusic.config import UserConfig
|
||||
from swingmusic.models import Album as AlbumModel, Artist as ArtistModel, Track as TrackModel
|
||||
from swingmusic.models.favorite import Favorite
|
||||
from swingmusic.models.lastfm import SimilarArtist
|
||||
from swingmusic.models.logger import TrackLog
|
||||
from swingmusic.models.playlist import Playlist
|
||||
from swingmusic.models.plugins import Plugin
|
||||
from swingmusic.models.user import User
|
||||
|
||||
|
||||
def row_to_dict(row: Any):
|
||||
@@ -3,7 +3,7 @@ Contains methods relating to albums.
|
||||
"""
|
||||
|
||||
|
||||
from app.models.track import Track
|
||||
from swingmusic.models.track import Track
|
||||
|
||||
|
||||
def remove_duplicate_on_merge_versions(tracks: list[Track]):
|
||||
@@ -12,16 +12,16 @@ from PIL import Image, PngImagePlugin, UnidentifiedImageError
|
||||
from requests.exceptions import ConnectionError as RequestConnectionError
|
||||
from requests.exceptions import ReadTimeout
|
||||
|
||||
from app import settings
|
||||
from app.models.artist import Artist
|
||||
from app.store.artists import ArtistStore
|
||||
from swingmusic import settings
|
||||
from swingmusic.models.artist import Artist
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
|
||||
# from app.db.libdata import ArtistTable
|
||||
# from swingmusic.db.libdata import ArtistTable
|
||||
|
||||
# from app.store import artists as artist_store
|
||||
# from app.store.tracks import TrackStore
|
||||
from app.utils.hashing import create_hash
|
||||
from app.utils.progressbar import tqdm
|
||||
# from swingmusic.store import artists as artist_store
|
||||
# from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.hashing import create_hash
|
||||
from swingmusic.utils.progressbar import tqdm
|
||||
|
||||
|
||||
LARGE_ENOUGH_NUMBER = 100
|
||||
@@ -6,13 +6,13 @@ from pathlib import Path
|
||||
|
||||
import colorgram
|
||||
|
||||
from app import settings
|
||||
from swingmusic import settings
|
||||
|
||||
from app.db.userdata import LibDataTable
|
||||
from app.logger import log
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.utils.progressbar import tqdm
|
||||
from swingmusic.db.userdata import LibDataTable
|
||||
from swingmusic.logger import log
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.utils.progressbar import tqdm
|
||||
|
||||
def get_image_colors(image: str, count=1) -> list[str]:
|
||||
"""Extracts n number of the most dominant colors from an image."""
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Any
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
|
||||
def get_extra_info(hash: str, type: str):
|
||||
@@ -1,13 +1,13 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from app.lib.sortlib import sort_folders, sort_tracks
|
||||
from app.logger import log
|
||||
from app.models import Folder
|
||||
from app.serializers.track import serialize_tracks
|
||||
from app.utils.filesystem import SUPPORTED_FILES
|
||||
from app.store.folder import FolderStore
|
||||
from app.utils.wintools import win_replace_slash
|
||||
from swingmusic.lib.sortlib import sort_folders, sort_tracks
|
||||
from swingmusic.logger import log
|
||||
from swingmusic.models import Folder
|
||||
from swingmusic.serializers.track import serialize_tracks
|
||||
from swingmusic.utils.filesystem import SUPPORTED_FILES
|
||||
from swingmusic.store.folder import FolderStore
|
||||
from swingmusic.utils.wintools import win_replace_slash
|
||||
|
||||
|
||||
def create_folder(path: str, trackcount=0) -> Folder:
|
||||
@@ -1,12 +1,12 @@
|
||||
from app.db.userdata import MixTable
|
||||
from app.plugins.mixes import MixesPlugin
|
||||
from swingmusic.db.userdata import MixTable
|
||||
from swingmusic.plugins.mixes import MixesPlugin
|
||||
|
||||
|
||||
def find_mix(mixid: str, sourcehash: str):
|
||||
"""
|
||||
Find a mix in the homepage store or the db.
|
||||
"""
|
||||
from app.store.homepage import HomepageStore
|
||||
from swingmusic.store.homepage import HomepageStore
|
||||
|
||||
mixtype = "custom_mixes" if mixid[0] == "t" else "artist_mixes"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import os
|
||||
from app.db.userdata import PlaylistTable
|
||||
from app.lib.home import find_mix
|
||||
from app.lib.home.recentlyadded import get_recently_added_playlist
|
||||
from app.lib.home.recentlyplayed import get_recently_played_playlist
|
||||
from app.models.logger import TrackLog
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic.db.userdata import PlaylistTable
|
||||
from swingmusic.lib.home import find_mix
|
||||
from swingmusic.lib.home.recentlyadded import get_recently_added_playlist
|
||||
from swingmusic.lib.home.recentlyplayed import get_recently_played_playlist
|
||||
from swingmusic.models.logger import TrackLog
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
|
||||
def create_items(entries: list[TrackLog], limit: int):
|
||||
@@ -1,6 +1,6 @@
|
||||
from app.db.userdata import ScrobbleTable
|
||||
from app.lib.home.create_items import create_items
|
||||
from app.models.logger import TrackLog
|
||||
from swingmusic.db.userdata import ScrobbleTable
|
||||
from swingmusic.lib.home.create_items import create_items
|
||||
from swingmusic.models.logger import TrackLog
|
||||
|
||||
|
||||
def get_recently_played(
|
||||
@@ -1,17 +1,17 @@
|
||||
from datetime import datetime
|
||||
|
||||
from app.lib.playlistlib import get_first_4_images
|
||||
from app.models.playlist import Playlist
|
||||
from app.models.track import Track
|
||||
from swingmusic.lib.playlistlib import get_first_4_images
|
||||
from swingmusic.models.playlist import Playlist
|
||||
from swingmusic.models.track import Track
|
||||
|
||||
from app.store.tracks import TrackStore
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
|
||||
from itertools import groupby
|
||||
|
||||
from app.utils import flatten
|
||||
from app.utils.dates import (
|
||||
from swingmusic.utils import flatten
|
||||
from swingmusic.utils.dates import (
|
||||
create_new_date,
|
||||
date_string_to_time_passed,
|
||||
)
|
||||
@@ -1,13 +1,13 @@
|
||||
from datetime import datetime
|
||||
|
||||
from app.models.playlist import Playlist
|
||||
from app.lib.playlistlib import get_first_4_images
|
||||
from app.utils.dates import (
|
||||
from swingmusic.models.playlist import Playlist
|
||||
from swingmusic.lib.playlistlib import get_first_4_images
|
||||
from swingmusic.utils.dates import (
|
||||
create_new_date,
|
||||
date_string_to_time_passed,
|
||||
)
|
||||
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
|
||||
def get_recently_played_playlist(limit: int = 100):
|
||||
@@ -1,17 +1,17 @@
|
||||
from app.db.userdata import FavoritesTable, MixTable, PlaylistTable
|
||||
from app.lib.home import find_mix
|
||||
from app.lib.home.recentlyadded import get_recently_added_playlist
|
||||
from app.lib.home.recentlyplayed import get_recently_played_playlist
|
||||
from app.lib.playlistlib import get_first_4_images
|
||||
from app.serializers.album import album_serializer
|
||||
from app.serializers.artist import serialize_for_card
|
||||
from app.serializers.playlist import serialize_for_card as serialize_playlist
|
||||
from app.serializers.track import serialize_track
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.folder import FolderStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.dates import timestamp_to_time_passed
|
||||
from swingmusic.db.userdata import FavoritesTable, MixTable, PlaylistTable
|
||||
from swingmusic.lib.home import find_mix
|
||||
from swingmusic.lib.home.recentlyadded import get_recently_added_playlist
|
||||
from swingmusic.lib.home.recentlyplayed import get_recently_played_playlist
|
||||
from swingmusic.lib.playlistlib import get_first_4_images
|
||||
from swingmusic.serializers.album import album_serializer
|
||||
from swingmusic.serializers.artist import serialize_for_card
|
||||
from swingmusic.serializers.playlist import serialize_for_card as serialize_playlist
|
||||
from swingmusic.serializers.track import serialize_track
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.folder import FolderStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.dates import timestamp_to_time_passed
|
||||
|
||||
|
||||
def recover_items(items: list[dict]):
|
||||
@@ -1,19 +1,19 @@
|
||||
import gc
|
||||
from time import time
|
||||
from app.lib.mapstuff import (
|
||||
from swingmusic.lib.mapstuff import (
|
||||
map_album_colors,
|
||||
map_artist_colors,
|
||||
map_favorites,
|
||||
map_scrobble_data,
|
||||
)
|
||||
from app.lib.populate import CordinateMedia
|
||||
from app.lib.recipes.recents import RecentlyAdded
|
||||
from app.lib.tagger import IndexTracks
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.folder import FolderStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.threading import background
|
||||
from swingmusic.lib.populate import CordinateMedia
|
||||
from swingmusic.lib.recipes.recents import RecentlyAdded
|
||||
from swingmusic.lib.tagger import IndexTracks
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.folder import FolderStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
from swingmusic.utils.threading import background
|
||||
|
||||
|
||||
class IndexEverything:
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
from typing import Iterable
|
||||
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
|
||||
def split_line(line: str):
|
||||
@@ -1,7 +1,7 @@
|
||||
from app.db.userdata import LibDataTable, FavoritesTable, ScrobbleTable
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic.db.userdata import LibDataTable, FavoritesTable, ScrobbleTable
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
|
||||
from typing import Any
|
||||
@@ -1,10 +1,10 @@
|
||||
import json
|
||||
from typing import Any
|
||||
from app.serializers.album import serialize_for_card
|
||||
from app.serializers.artist import serialize_for_card as serialize_artist
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.utils.hashing import create_hash
|
||||
from swingmusic.serializers.album import serialize_for_card
|
||||
from swingmusic.serializers.artist import serialize_for_card as serialize_artist
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.utils.hashing import create_hash
|
||||
|
||||
|
||||
def validate_page_items(items: list[dict[str, str]], existing: list[dict[str, str]]):
|
||||
@@ -9,10 +9,10 @@ from typing import Any
|
||||
|
||||
from PIL import Image, ImageSequence
|
||||
|
||||
from app import settings
|
||||
from app.models.track import Track
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic import settings
|
||||
from swingmusic.models.track import Track
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
|
||||
def create_thumbnail(image: Any, img_path: str) -> str:
|
||||
@@ -6,20 +6,20 @@ import platform
|
||||
from requests import ConnectionError as RequestConnectionError
|
||||
from requests import ReadTimeout
|
||||
|
||||
from app import settings
|
||||
from app.lib.artistlib import CheckArtistImages
|
||||
from app.lib.colorlib import ProcessAlbumColors, ProcessArtistColors
|
||||
from app.lib.taglib import extract_thumb
|
||||
from app.logger import log
|
||||
from app.models import Album, Artist
|
||||
from app.models.lastfm import SimilarArtist
|
||||
from app.requests.artists import fetch_similar_artists
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.utils.network import has_connection
|
||||
from app.utils.progressbar import tqdm
|
||||
from swingmusic import settings
|
||||
from swingmusic.lib.artistlib import CheckArtistImages
|
||||
from swingmusic.lib.colorlib import ProcessAlbumColors, ProcessArtistColors
|
||||
from swingmusic.lib.taglib import extract_thumb
|
||||
from swingmusic.logger import log
|
||||
from swingmusic.models import Album, Artist
|
||||
from swingmusic.models.lastfm import SimilarArtist
|
||||
from swingmusic.requests.artists import fetch_similar_artists
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.utils.network import has_connection
|
||||
from swingmusic.utils.progressbar import tqdm
|
||||
|
||||
from app.db.userdata import SimilarArtistTable
|
||||
from swingmusic.db.userdata import SimilarArtistTable
|
||||
|
||||
|
||||
class CordinateMedia:
|
||||
@@ -1,7 +1,7 @@
|
||||
from app.db.userdata import UserTable
|
||||
from app.lib.recipes import HomepageRoutine
|
||||
from app.plugins.mixes import MixesPlugin
|
||||
from app.store.homepage import HomepageStore
|
||||
from swingmusic.db.userdata import UserTable
|
||||
from swingmusic.lib.recipes import HomepageRoutine
|
||||
from swingmusic.plugins.mixes import MixesPlugin
|
||||
from swingmusic.store.homepage import HomepageStore
|
||||
|
||||
|
||||
class ArtistMixes(HomepageRoutine):
|
||||
@@ -1,10 +1,10 @@
|
||||
from pprint import pprint
|
||||
from app.db.userdata import UserTable
|
||||
from app.lib.recipes import HomepageRoutine
|
||||
from app.lib.recipes.artistmixes import ArtistMixes
|
||||
from app.models.mix import Mix
|
||||
from app.plugins.mixes import MixesPlugin
|
||||
from app.store.homepage import HomepageStore
|
||||
from swingmusic.db.userdata import UserTable
|
||||
from swingmusic.lib.recipes import HomepageRoutine
|
||||
from swingmusic.lib.recipes.artistmixes import ArtistMixes
|
||||
from swingmusic.models.mix import Mix
|
||||
from swingmusic.plugins.mixes import MixesPlugin
|
||||
from swingmusic.store.homepage import HomepageStore
|
||||
|
||||
|
||||
class BecauseYouListened(HomepageRoutine):
|
||||
@@ -1,9 +1,9 @@
|
||||
import pprint
|
||||
from app.db.userdata import ScrobbleTable, UserTable
|
||||
from app.lib.home.recentlyadded import get_recently_added_items
|
||||
from app.lib.home.get_recently_played import get_recently_played
|
||||
from app.lib.recipes import HomepageRoutine
|
||||
from app.store.homepage import HomepageStore
|
||||
from swingmusic.db.userdata import ScrobbleTable, UserTable
|
||||
from swingmusic.lib.home.recentlyadded import get_recently_added_items
|
||||
from swingmusic.lib.home.get_recently_played import get_recently_played
|
||||
from swingmusic.lib.recipes import HomepageRoutine
|
||||
from swingmusic.store.homepage import HomepageStore
|
||||
|
||||
|
||||
class RecentlyPlayed(HomepageRoutine):
|
||||
@@ -1,12 +1,12 @@
|
||||
from gettext import ngettext
|
||||
import pendulum
|
||||
|
||||
from app.crons.cron import CronJob
|
||||
from app.db.userdata import UserTable
|
||||
from app.lib.recipes import HomepageRoutine
|
||||
from app.store.homepage import HomepageStore
|
||||
from app.utils.dates import get_date_range, seconds_to_time_string
|
||||
from app.utils.stats import get_artists_in_period
|
||||
from swingmusic.crons.cron import CronJob
|
||||
from swingmusic.db.userdata import UserTable
|
||||
from swingmusic.lib.recipes import HomepageRoutine
|
||||
from swingmusic.store.homepage import HomepageStore
|
||||
from swingmusic.utils.dates import get_date_range, seconds_to_time_string
|
||||
from swingmusic.utils.stats import get_artists_in_period
|
||||
|
||||
|
||||
class TopArtists(CronJob, HomepageRoutine):
|
||||
@@ -7,27 +7,27 @@ from typing import Any, Generator, List, TypeVar
|
||||
from rapidfuzz import process, utils, fuzz
|
||||
from unidecode import unidecode
|
||||
|
||||
from app import models
|
||||
from app.config import UserConfig
|
||||
from swingmusic import models
|
||||
from swingmusic.config import UserConfig
|
||||
|
||||
# from app.db.libdata import AlbumTable, ArtistTable, TrackTable
|
||||
# from swingmusic.db.libdata import AlbumTable, ArtistTable, TrackTable
|
||||
|
||||
# from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
||||
from app.models.album import Album
|
||||
from app.models.artist import Artist
|
||||
from app.models.enums import FavType
|
||||
from app.models.playlist import Playlist
|
||||
from app.models.track import Track
|
||||
from app.serializers.album import serialize_for_card as serialize_album
|
||||
from app.serializers.album import serialize_for_card_many as serialize_albums
|
||||
from app.serializers.artist import serialize_for_card, serialize_for_cards
|
||||
from app.serializers.track import serialize_track, serialize_tracks
|
||||
# from swingmusic.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
||||
from swingmusic.models.album import Album
|
||||
from swingmusic.models.artist import Artist
|
||||
from swingmusic.models.enums import FavType
|
||||
from swingmusic.models.playlist import Playlist
|
||||
from swingmusic.models.track import Track
|
||||
from swingmusic.serializers.album import serialize_for_card as serialize_album
|
||||
from swingmusic.serializers.album import serialize_for_card_many as serialize_albums
|
||||
from swingmusic.serializers.artist import serialize_for_card, serialize_for_cards
|
||||
from swingmusic.serializers.track import serialize_track, serialize_tracks
|
||||
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from swingmusic.store.albums import AlbumStore
|
||||
from swingmusic.store.artists import ArtistStore
|
||||
from swingmusic.store.tracks import TrackStore
|
||||
|
||||
from app.utils.remove_duplicates import remove_duplicates
|
||||
from swingmusic.utils.remove_duplicates import remove_duplicates
|
||||
|
||||
# ratio = fuzz.ratio
|
||||
# wratio = fuzz.WRatio
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user