diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2032e5f --- /dev/null +++ b/.env.example @@ -0,0 +1,14 @@ +BOT_TOKEN = +FILES_CHAT = +ADMIN_ID = + +DB_PATH = /app/data/db.db + +SPOTIFY_CLIENT_ID = +SPOTIFY_CLIENT_SECRET = + +DEEZER_ARL = + +SOUNDCLOUD_CLIENT_ID = + +GENIUS_CLIENT_ACCESS = diff --git a/.gitignore b/.gitignore index ea314b2..2a3c261 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ /.idea/ /tests/ -poetry.lock +.env config.toml **/__pycache__/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3f56067 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM ghcr.io/astral-sh/uv:python3.12-alpine + +WORKDIR /app + +COPY pyproject.toml uv.lock ./ +COPY lib ./lib +RUN uv sync --frozen + +ENV PATH="/app/.venv/bin:$PATH" + +COPY . /app/src +WORKDIR /app/src + +CMD ["python3", "-m", "bot"] diff --git a/bot/common.py b/bot/common.py index 3158a9e..2a6d276 100644 --- a/bot/common.py +++ b/bot/common.py @@ -3,11 +3,11 @@ from rich.console import Console from bot.modules.fsm import InDbStorage -from .utils.config import config +from .utils import env -bot = Bot(token=config.telegram.bot_token) +bot = Bot(token=env.BOT_TOKEN) dp = Dispatcher(storage=InDbStorage()) console = Console() -__all__ = ["bot", "dp", "config", "console"] +__all__ = ["bot", "dp", "console"] diff --git a/bot/handlers/on_chosen/deezer.py b/bot/handlers/on_chosen/deezer.py index c1b53ec..66f5d65 100644 --- a/bot/handlers/on_chosen/deezer.py +++ b/bot/handlers/on_chosen/deezer.py @@ -8,7 +8,7 @@ from aiogram.types import ( from bot.modules.database import db from bot.modules.deezer import DeezerBytestream, deezer -from bot.utils.config import config +from bot.utils import env router = Router() @@ -20,7 +20,7 @@ async def on_new_chosen(chosen_result: ChosenInlineResult, bot: Bot): ).to_bytestream() audio = await bot.send_audio( - chat_id=config.telegram.files_chat, + chat_id=env.FILES_CHAT, audio=BufferedInputFile( file=bytestream.file, filename=bytestream.filename, diff --git a/bot/handlers/on_chosen/recode_cached.py b/bot/handlers/on_chosen/recode_cached.py index f69fd95..b41c24c 100644 --- a/bot/handlers/on_chosen/recode_cached.py +++ b/bot/handlers/on_chosen/recode_cached.py @@ -6,7 +6,7 @@ from aiogram.types import BufferedInputFile, ChosenInlineResult, InputMediaAudio from bot.modules.database import db from bot.modules.settings import UserSettings from bot.modules.youtube.downloader import YouTubeBytestream -from bot.utils.config import config +from bot.utils import env router = Router() @@ -42,7 +42,7 @@ async def on_cached_chosen( ) message = await bot.forward_message( - config.telegram.files_chat, config.telegram.files_chat, db.recoded[song_id] + env.FILES_CHAT, env.FILES_CHAT, db.recoded[song_id] ) song_io: BytesIO = await bot.download( # type: ignore @@ -60,7 +60,7 @@ async def on_cached_chosen( await bytestream.rerender() audio = await bot.send_audio( - chat_id=config.telegram.files_chat, + chat_id=env.FILES_CHAT, audio=BufferedInputFile( file=bytestream.file, filename=bytestream.filename, diff --git a/bot/handlers/on_chosen/soundcloud.py b/bot/handlers/on_chosen/soundcloud.py index 3638793..a39550e 100644 --- a/bot/handlers/on_chosen/soundcloud.py +++ b/bot/handlers/on_chosen/soundcloud.py @@ -8,7 +8,7 @@ from aiogram.types import ( from bot.modules.database import db from bot.modules.soundcloud import SoundCloudBytestream, soundcloud -from bot.utils.config import config +from bot.utils import env router = Router() @@ -22,7 +22,7 @@ async def on_new_chosen(chosen_result: ChosenInlineResult, bot: Bot): ).to_bytestream() audio = await bot.send_audio( - chat_id=config.telegram.files_chat, + chat_id=env.FILES_CHAT, audio=BufferedInputFile( file=bytestream.file, filename=bytestream.filename, diff --git a/bot/handlers/on_chosen/spotify.py b/bot/handlers/on_chosen/spotify.py index 6253c30..16f1527 100644 --- a/bot/handlers/on_chosen/spotify.py +++ b/bot/handlers/on_chosen/spotify.py @@ -12,7 +12,7 @@ from bot.modules.settings import UserSettings from bot.modules.spotify import spotify from bot.modules.youtube import AgeRestrictedError, youtube from bot.modules.youtube.song import SongItem -from bot.utils.config import config +from bot.utils import env router = Router() @@ -55,7 +55,7 @@ async def on_new_chosen( bytestream = await yt_song.to_bytestream() audio = await bot.send_audio( - chat_id=config.telegram.files_chat, + chat_id=env.FILES_CHAT, audio=BufferedInputFile( file=bytestream.file, filename=bytestream.filename, @@ -87,7 +87,7 @@ async def on_new_chosen( ).to_bytestream() audio = await bot.send_audio( - chat_id=config.telegram.files_chat, + chat_id=env.FILES_CHAT, audio=BufferedInputFile( file=bytestream.file, filename=bytestream.filename, @@ -130,7 +130,7 @@ async def on_new_chosen( await bytestream.rerender() audio = await bot.send_audio( - chat_id=config.telegram.files_chat, + chat_id=env.FILES_CHAT, audio=BufferedInputFile( file=bytestream.file, filename=bytestream.filename, diff --git a/bot/handlers/on_chosen/youtube.py b/bot/handlers/on_chosen/youtube.py index 75bfcb5..6d4550c 100644 --- a/bot/handlers/on_chosen/youtube.py +++ b/bot/handlers/on_chosen/youtube.py @@ -9,7 +9,7 @@ from aiogram.types import ( from bot.modules.database import db from bot.modules.settings import UserSettings from bot.modules.youtube import AgeRestrictedError, youtube -from bot.utils.config import config +from bot.utils import env router = Router() @@ -32,7 +32,7 @@ async def on_new_chosen( return audio = await bot.send_audio( - chat_id=config.telegram.files_chat, + chat_id=env.FILES_CHAT, audio=BufferedInputFile( file=bytestream.file, filename=bytestream.filename, @@ -61,7 +61,7 @@ async def on_new_chosen( await bytestream.rerender() audio = await bot.send_audio( - chat_id=config.telegram.files_chat, + chat_id=env.FILES_CHAT, audio=BufferedInputFile( file=bytestream.file, filename=bytestream.filename, diff --git a/bot/modules/database/db_model.py b/bot/modules/database/db_model.py index 23fa2b0..1742b21 100644 --- a/bot/modules/database/db_model.py +++ b/bot/modules/database/db_model.py @@ -1,8 +1,9 @@ from sqlitedict import SqliteDict -from bot.utils.config import config +from bot.utils import env class DBDict(SqliteDict): def __init__(self, tablename: str): - super().__init__(config.local.db_path, tablename=tablename, autocommit=True) + super().__init__(env.DB_PATH, tablename=tablename, autocommit=True) +F \ No newline at end of file diff --git a/bot/modules/deezer/__init__.py b/bot/modules/deezer/__init__.py index 01bf107..0a5724c 100644 --- a/bot/modules/deezer/__init__.py +++ b/bot/modules/deezer/__init__.py @@ -1,10 +1,10 @@ -from bot.utils.config import config +from bot.utils import env from .deezer import Deezer from .downloader import DeezerBytestream deezer = Deezer( - arl=config.tokens.deezer.arl, + arl=env.DEEZER_ARL, ) __all__ = ["deezer", "DeezerBytestream"] diff --git a/bot/modules/soundcloud/__init__.py b/bot/modules/soundcloud/__init__.py index 1e6c4b7..6da1e71 100644 --- a/bot/modules/soundcloud/__init__.py +++ b/bot/modules/soundcloud/__init__.py @@ -1,10 +1,10 @@ -from bot.utils.config import config +from bot.utils import env from .downloader import SoundCloudBytestream from .soundcloud import SoundCloud soundcloud = SoundCloud( - client_id=config.tokens.soundcloud.client_id, + client_id=env.SOUNDCLOUD_CLIENT_ID, ) __all__ = ["soundcloud", "SoundCloudBytestream"] diff --git a/bot/modules/spotify/__init__.py b/bot/modules/spotify/__init__.py index 44103dd..0a9847f 100644 --- a/bot/modules/spotify/__init__.py +++ b/bot/modules/spotify/__init__.py @@ -1,10 +1,10 @@ -from bot.utils.config import config +from bot.utils import env from .spotify import Spotify spotify = Spotify( - client_id=config.tokens.spotify.client_id, - client_secret=config.tokens.spotify.client_secret, + client_id=env.SPOTIFY_CLIENT_ID, + client_secret=env.SPOTIFY_CLIENT_SECRET, ) __all__ = ["spotify"] diff --git a/bot/utils/__init__.py b/bot/utils/__init__.py index e69de29..8dcce20 100644 --- a/bot/utils/__init__.py +++ b/bot/utils/__init__.py @@ -0,0 +1 @@ +from .config import config diff --git a/bot/utils/env.py b/bot/utils/env.py new file mode 100644 index 0000000..25a23a4 --- /dev/null +++ b/bot/utils/env.py @@ -0,0 +1,26 @@ +import os +import sys + +from dotenv import load_dotenv + +try: + load_dotenv() + + BOT_TOKEN = os.environ["BOT_TOKEN"] + FILES_CHAT = os.environ["FILES_CHAT"] + ADMIN_ID = os.environ["ADMIN_ID"] + + DB_PATH = os.environ["DB_PATH"] + + SPOTIFY_CLIENT_ID = os.environ["SPOTIFY_CLIENT_ID"] + SPOTIFY_CLIENT_SECRET = os.environ["SPOTIFY_CLIENT_SECRET"] + + DEEZER_ARL = os.environ["DEEZER_ARL"] + + SOUNDCLOUD_CLIENT_ID = os.environ["SOUNDCLOUD_CLIENT_ID"] + + GENIUS_CLIENT_ACCESS = os.environ["GENIUS_CLIENT_ACCESS"] + +except KeyError as e: + print("Can't parse environment", e) + sys.exit(1) diff --git a/config.toml.example b/config.toml.example deleted file mode 100644 index 446ae79..0000000 --- a/config.toml.example +++ /dev/null @@ -1,21 +0,0 @@ -[telegram] -bot_token = '' -files_chat = 0 -admin_id = 0 - -[local] -db_path = 'db.db' -app_id = 'ANY-MUSIC-BOT' - -[tokens.spotify] -client_id = '' -client_secret = '' - -[tokens.deezer] -arl = '' - -[tokens.soundcloud] -client_id = '' - -[tokens.genius] -client_acces = '' diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d2fc772 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +services: + bot: + build: + context: . + dockerfile: Dockerfile + command: "python3 -m bot" + env_file: + - .env + volumes: + - ./:/app/src + - data:/app/data + +volumes: + data: diff --git a/pyproject.toml b/pyproject.toml index ac5d39e..3639028 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ dependencies = [ "m3u8>=5.1.0,<6", "cryptography>=43.0.0,<44", "pytubefix>=8.2.0,<9", + "python-dotenv>=1.0.1", ] [tool.uv.sources] diff --git a/uv.lock b/uv.lock index 3a303c2..88cec01 100644 --- a/uv.lock +++ b/uv.lock @@ -1,12 +1,12 @@ version = 1 -requires-python = ">=3.11, <4" +requires-python = ">=3.11" resolution-markers = [ "python_full_version < '3.11.3' and platform_python_implementation != 'PyPy'", "python_full_version >= '3.11.3' and python_full_version < '3.13' and platform_python_implementation != 'PyPy'", - "python_full_version >= '3.13' and platform_python_implementation != 'PyPy'", + "python_full_version >= '3.13' and python_full_version < '4' and platform_python_implementation != 'PyPy'", "python_full_version < '3.11.3' and platform_python_implementation == 'PyPy'", "python_full_version >= '3.11.3' and python_full_version < '3.13' and platform_python_implementation == 'PyPy'", - "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", + "python_full_version >= '3.13' and python_full_version < '4' and platform_python_implementation == 'PyPy'", ] [[package]] @@ -23,12 +23,12 @@ name = "aiogram" version = "3.13.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "aiofiles" }, - { name = "aiohttp" }, - { name = "certifi" }, - { name = "magic-filter" }, - { name = "pydantic" }, - { name = "typing-extensions" }, + { name = "aiofiles", marker = "python_full_version < '4'" }, + { name = "aiohttp", marker = "python_full_version < '4'" }, + { name = "certifi", marker = "python_full_version < '4'" }, + { name = "magic-filter", marker = "python_full_version < '4'" }, + { name = "pydantic", marker = "python_full_version < '4'" }, + { name = "typing-extensions", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ea/34/192e1166d9dbb5c53a4654a0dbf69a3c6e91d0f9e0d77adbb0544ff23dda/aiogram-3.13.1.tar.gz", hash = "sha256:2674640ae74501ae30e68a5354e03f12e10db3adbcbd475bb56904536288c9c9", size = 1347281 } wheels = [ @@ -49,12 +49,12 @@ name = "aiohttp" version = "3.10.10" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "yarl" }, + { name = "aiohappyeyeballs", marker = "python_full_version < '4'" }, + { name = "aiosignal", marker = "python_full_version < '4'" }, + { name = "attrs", marker = "python_full_version < '4'" }, + { name = "frozenlist", marker = "python_full_version < '4'" }, + { name = "multidict", marker = "python_full_version < '4'" }, + { name = "yarl", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/17/7e/16e57e6cf20eb62481a2f9ce8674328407187950ccc602ad07c685279141/aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a", size = 7542993 } wheels = [ @@ -110,7 +110,7 @@ name = "aiosignal" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "frozenlist" }, + { name = "frozenlist", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ae/67/0952ed97a9793b4958e5736f6d2b346b414a2cd63e82d05940032f45b32f/aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", size = 19422 } wheels = [ @@ -131,8 +131,8 @@ name = "anyio" version = "3.7.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "idna" }, - { name = "sniffio" }, + { name = "idna", marker = "python_full_version < '4'" }, + { name = "sniffio", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/28/99/2dfd53fd55ce9838e6ff2d4dac20ce58263798bd1a0dbe18b3a9af3fcfce/anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", size = 142927 } wheels = [ @@ -144,22 +144,23 @@ name = "anymusicbot" version = "0.1.0" source = { virtual = "." } dependencies = [ - { name = "aiogram" }, - { name = "aiohttp" }, - { name = "attrs" }, - { name = "cryptography" }, - { name = "icecream" }, - { name = "m3u8" }, - { name = "nest-asyncio" }, - { name = "pydub" }, - { name = "pytubefix" }, - { name = "rich" }, - { name = "setuptools" }, - { name = "shazamio" }, - { name = "spotipy" }, - { name = "sqlitedict" }, - { name = "wheel" }, - { name = "ytmusicapi" }, + { name = "aiogram", marker = "python_full_version < '4'" }, + { name = "aiohttp", marker = "python_full_version < '4'" }, + { name = "attrs", marker = "python_full_version < '4'" }, + { name = "cryptography", marker = "python_full_version < '4'" }, + { name = "icecream", marker = "python_full_version < '4'" }, + { name = "m3u8", marker = "python_full_version < '4'" }, + { name = "nest-asyncio", marker = "python_full_version < '4'" }, + { name = "pydub", marker = "python_full_version < '4'" }, + { name = "python-dotenv", marker = "python_full_version < '4'" }, + { name = "pytubefix", marker = "python_full_version < '4'" }, + { name = "rich", marker = "python_full_version < '4'" }, + { name = "setuptools", marker = "python_full_version < '4'" }, + { name = "shazamio", marker = "python_full_version < '4'" }, + { name = "spotipy", marker = "python_full_version < '4'" }, + { name = "sqlitedict", marker = "python_full_version < '4'" }, + { name = "wheel", marker = "python_full_version < '4'" }, + { name = "ytmusicapi", marker = "python_full_version < '4'" }, ] [package.metadata] @@ -172,6 +173,7 @@ requires-dist = [ { name = "m3u8", specifier = ">=5.1.0,<6" }, { name = "nest-asyncio", specifier = ">=1.5.8,<2" }, { name = "pydub", specifier = ">=0.25.1,<0.26" }, + { name = "python-dotenv", specifier = ">=1.0.1" }, { name = "pytubefix", specifier = ">=8.2.0,<9" }, { name = "rich", specifier = ">=13.6.0,<14" }, { name = "setuptools", specifier = ">=72.1.0,<73" }, @@ -187,7 +189,7 @@ name = "asttokens" version = "2.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "six" }, + { name = "six", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/45/1d/f03bcb60c4a3212e15f99a56085d93093a497718adf828d050b9d675da81/asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0", size = 62284 } wheels = [ @@ -226,7 +228,7 @@ name = "cffi" version = "1.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pycparser", marker = "platform_python_implementation != 'PyPy'" }, + { name = "pycparser", marker = "python_full_version < '4' and platform_python_implementation != 'PyPy'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } wheels = [ @@ -334,7 +336,7 @@ name = "cryptography" version = "43.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, + { name = "cffi", marker = "python_full_version < '4' and platform_python_implementation != 'PyPy'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", size = 686989 } wheels = [ @@ -434,10 +436,10 @@ name = "icecream" version = "2.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "asttokens" }, - { name = "colorama" }, - { name = "executing" }, - { name = "pygments" }, + { name = "asttokens", marker = "python_full_version < '4'" }, + { name = "colorama", marker = "python_full_version < '4'" }, + { name = "executing", marker = "python_full_version < '4'" }, + { name = "pygments", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/8b/ae6ebc9fc423f9397a0982990c86f1fe94077df729ef452c9a847fb16ae6/icecream-2.1.3.tar.gz", hash = "sha256:0aa4a7c3374ec36153a1d08f81e3080e83d8ac1eefd97d2f4fe9544e8f9b49de", size = 14722 } wheels = [ @@ -476,7 +478,7 @@ name = "markdown-it-py" version = "3.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "mdurl" }, + { name = "mdurl", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } wheels = [ @@ -650,9 +652,9 @@ name = "pydantic" version = "2.9.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, + { name = "annotated-types", marker = "python_full_version < '4'" }, + { name = "pydantic-core", marker = "python_full_version < '4'" }, + { name = "typing-extensions", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } wheels = [ @@ -664,7 +666,7 @@ name = "pydantic-core" version = "2.23.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } wheels = [ @@ -724,6 +726,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, ] +[[package]] +name = "python-dotenv" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, +] + [[package]] name = "pytubefix" version = "8.2.0" @@ -750,10 +761,10 @@ name = "requests" version = "2.32.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, + { name = "certifi", marker = "python_full_version < '4'" }, + { name = "charset-normalizer", marker = "python_full_version < '4'" }, + { name = "idna", marker = "python_full_version < '4'" }, + { name = "urllib3", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } wheels = [ @@ -765,8 +776,8 @@ name = "rich" version = "13.9.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, + { name = "markdown-it-py", marker = "python_full_version < '4'" }, + { name = "pygments", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 } wheels = [ @@ -787,13 +798,13 @@ name = "shazamio" version = "0.0.6" source = { directory = "lib/ShazamIO" } dependencies = [ - { name = "aiofiles" }, - { name = "aiohttp" }, - { name = "anyio" }, - { name = "dataclass-factory" }, - { name = "numpy" }, - { name = "pydantic" }, - { name = "pydub" }, + { name = "aiofiles", marker = "python_full_version < '4'" }, + { name = "aiohttp", marker = "python_full_version < '4'" }, + { name = "anyio", marker = "python_full_version < '4'" }, + { name = "dataclass-factory", marker = "python_full_version < '4'" }, + { name = "numpy", marker = "python_full_version < '4'" }, + { name = "pydantic", marker = "python_full_version < '4'" }, + { name = "pydub", marker = "python_full_version < '4'" }, ] [package.metadata] @@ -830,9 +841,9 @@ name = "spotipy" version = "2.24.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "redis" }, - { name = "requests" }, - { name = "urllib3" }, + { name = "redis", marker = "python_full_version < '4'" }, + { name = "requests", marker = "python_full_version < '4'" }, + { name = "urllib3", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9b/10/145a649207a9d4067846045cca71262b8ea2140d1df3fa78581fbf1b9ec0/spotipy-2.24.0.tar.gz", hash = "sha256:396af81e642086551af157270cdfe742c1739405871ba9dac1fa651b8649ef0d", size = 41708 } wheels = [ @@ -877,9 +888,9 @@ name = "yarl" version = "1.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "idna" }, - { name = "multidict" }, - { name = "propcache" }, + { name = "idna", marker = "python_full_version < '4'" }, + { name = "multidict", marker = "python_full_version < '4'" }, + { name = "propcache", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/54/9c/9c0a9bfa683fc1be7fdcd9687635151544d992cccd48892dc5e0a5885a29/yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47", size = 178163 } wheels = [ @@ -939,7 +950,7 @@ name = "ytmusicapi" version = "1.8.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "requests" }, + { name = "requests", marker = "python_full_version < '4'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/28/d2/c94548a3c29cf24a2e5c85cd95e86b1808803882b7835c37bfeab1ea9530/ytmusicapi-1.8.2.tar.gz", hash = "sha256:454facdf5907c32b77cb035f54c76d5a9d3fb0316933b1a1cecd06110ff85ecf", size = 284079 } wheels = [