diff --git a/.gitignore b/.gitignore index 2b5b4f9..97889a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Project files +scripts/playlists/*.txt + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/README.md b/README.md index 883d978..8750a25 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# ChristmasBot -Christmas Music Bot +# TuneBot +A very configurable Discord radio diff --git a/bot.py b/bot.py index bd991a8..85b7cd9 100644 --- a/bot.py +++ b/bot.py @@ -23,7 +23,7 @@ from discord.ext.commands.errors import NoEntryPointError from context import CustomContext -class ChristmasBot(commands.Bot): +class TuneBot(commands.Bot): lavalink: lavalink.Client invite_link: str @@ -110,7 +110,11 @@ class ChristmasBot(commands.Bot): await self.change_presence(activity=activity) -config = json.load(open("config.json", "r", encoding="utf-8")) +config_path = "config.json" +if len(sys.argv) > 1: + config_path = sys.argv[1] + +config = json.load(open(config_path, "r", encoding="utf-8")) redis_prefix = config["redis_prefix"] if __name__ == "__main__": @@ -123,4 +127,4 @@ if __name__ == "__main__": pass token = config.pop("token") - ChristmasBot(config).run(token, reconnect=True) + TuneBot(config).run(token, reconnect=True) diff --git a/cogs/information.py b/cogs/information.py index e185f18..c94763f 100644 --- a/cogs/information.py +++ b/cogs/information.py @@ -9,7 +9,7 @@ from discord.ext import commands from discord.ext import tasks from discord.ext.commands import Context -from bot import ChristmasBot +from bot import TuneBot from context import CustomContext from utils.database import AutoJoin from utils.EmbedGenerator import EmbedGenerator @@ -123,6 +123,6 @@ class InformationCog(BaseCog, name="Information"): await ctx.send(embed=embed) -def setup(bot: ChristmasBot): +def setup(bot: TuneBot): bot.remove_command("help") bot.add_cog(InformationCog(bot)) diff --git a/cogs/music.py b/cogs/music.py index 5f6db53..91a401f 100644 --- a/cogs/music.py +++ b/cogs/music.py @@ -15,7 +15,7 @@ from discord.ext.commands.context import Context from lavalink.models import AudioTrack from lavalink.models import DefaultPlayer -from bot import ChristmasBot +from bot import TuneBot from utils.classes import BaseCog from context import CustomContext from utils.database import AutoJoin @@ -245,8 +245,8 @@ class Music(BaseCog): if player.is_connected: await ctx.send("Already connected") return - - await self.fill_player_queue(player, self.bot.config["queue_buffer_size"]+1) + + await self.fill_player_queue(player, self.bot.config["queue_buffer_size"] + 1) if not player.is_playing: await player.play() @@ -309,5 +309,5 @@ class Music(BaseCog): await ctx.send(embed=embed) -def setup(bot: ChristmasBot): +def setup(bot: TuneBot): bot.add_cog(Music(bot)) diff --git a/cogs/owner.py b/cogs/owner.py index e4af4ae..65fc4c8 100644 --- a/cogs/owner.py +++ b/cogs/owner.py @@ -12,12 +12,12 @@ import discord from discord.ext import commands from discord.ext.commands.context import Context -from bot import ChristmasBot +from bot import TuneBot from utils.classes import BaseCog class OwnerCog(BaseCog): - def __init__(self, bot: ChristmasBot): + def __init__(self, bot: TuneBot): super().__init__(bot) self._last_result = None @@ -209,5 +209,5 @@ class OwnerCog(BaseCog): await message.edit(content=f"```fix\n{content}\n```") -def setup(bot: ChristmasBot): +def setup(bot: TuneBot): bot.add_cog(OwnerCog(bot)) diff --git a/cogs/settings.py b/cogs/settings.py index 05a4989..d7f13a8 100644 --- a/cogs/settings.py +++ b/cogs/settings.py @@ -2,10 +2,10 @@ from discord.ext import commands from utils.EmbedGenerator import EmbedGenerator from utils.classes import BaseCog from utils.database import AutoJoin -from bot import ChristmasBot +from bot import TuneBot from discord.ext.commands import Context -from bot import ChristmasBot +from bot import TuneBot from context import CustomContext from utils.database import AutoJoin from utils.EmbedGenerator import EmbedGenerator @@ -43,5 +43,5 @@ class SettingsCog(BaseCog, name="Settings"): await EmbedGenerator.Message(ctx, "Autojoin", "`disabled`") -def setup(bot: ChristmasBot): +def setup(bot: TuneBot): bot.add_cog(SettingsCog(bot)) diff --git a/poetry.lock b/poetry.lock index 3d45a28..8cfe0eb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -31,6 +31,18 @@ typing-extensions = "*" [package.extras] hiredis = ["hiredis (>=1.0)"] +[[package]] +name = "aiotube" +version = "1.3.5" +description = "Get YouTube Public Data without YouTubeAPI" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pytube = "*" +urllib3 = "*" + [[package]] name = "async-timeout" version = "3.0.1" @@ -92,6 +104,14 @@ jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] python2 = ["typed-ast (>=1.4.2)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "certifi" +version = "2021.10.8" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "cffi" version = "1.15.0" @@ -119,6 +139,17 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "charset-normalizer" +version = "2.0.7" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "dev" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + [[package]] name = "click" version = "8.0.3" @@ -320,6 +351,11 @@ six = "*" docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] +[[package]] +name = "pytube" +version = "11.0.1" +description = "Python 3 library for downloading YouTube Videos." + [[package]] name = "pyyaml" version = "6.0" @@ -328,6 +364,17 @@ category = "dev" optional = false python-versions = ">=3.6" +[[package]] +name = "redis" +version = "3.5.3" +description = "Python client for Redis key-value store" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +hiredis = ["hiredis (>=0.1.3)"] + [[package]] name = "regex" version = "2021.10.23" @@ -336,6 +383,24 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "requests" +version = "2.26.0" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] + [[package]] name = "six" version = "1.16.0" @@ -368,6 +433,19 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "urllib3" +version = "1.26.7" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + [[package]] name = "uvloop" version = "0.16.0" @@ -415,7 +493,7 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "7428479732f5183e24be61ddeee7230bafdd6b76920e2d6d548c6a091e570111" +content-hash = "3c3a2dd744428dff07d2a6fff8ccd9e529a8b3137fa6e8c8f68fe4b024c020e7" [metadata.files] aiohttp = [ @@ -437,6 +515,10 @@ aioredis = [ {file = "aioredis-2.0.0-py3-none-any.whl", hash = "sha256:9921d68a3df5c5cdb0d5b49ad4fc88a4cfdd60c108325df4f0066e8410c55ffb"}, {file = "aioredis-2.0.0.tar.gz", hash = "sha256:3a2de4b614e6a5f8e104238924294dc4e811aefbe17ddf52c04a93cbf06e67db"}, ] +aiotube = [ + {file = "aiotube-1.3.5-py3-none-any.whl", hash = "sha256:4dcef22dd27e6229b82186555c7f4779b62f751d669b9517b88d8d7af977338f"}, + {file = "aiotube-1.3.5.tar.gz", hash = "sha256:3b015060480136812249433b02b5d869ad62a82916a92fe741bf4f907b7a948b"}, +] async-timeout = [ {file = "async-timeout-3.0.1.tar.gz", hash = "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f"}, {file = "async_timeout-3.0.1-py3-none-any.whl", hash = "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"}, @@ -453,6 +535,10 @@ black = [ {file = "black-21.9b0-py3-none-any.whl", hash = "sha256:380f1b5da05e5a1429225676655dddb96f5ae8c75bdf91e53d798871b902a115"}, {file = "black-21.9b0.tar.gz", hash = "sha256:7de4cfc7eb6b710de325712d40125689101d21d25283eed7e9998722cf10eb91"}, ] +certifi = [ + {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, + {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, +] cffi = [ {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, @@ -513,6 +599,10 @@ chardet = [ {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, ] +charset-normalizer = [ + {file = "charset-normalizer-2.0.7.tar.gz", hash = "sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0"}, + {file = "charset_normalizer-2.0.7-py3-none-any.whl", hash = "sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b"}, +] click = [ {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, @@ -633,6 +723,14 @@ pynacl = [ {file = "PyNaCl-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420"}, {file = "PyNaCl-1.4.0.tar.gz", hash = "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505"}, ] +pytube = [ + {file = "pytube-11.0.1-py3-none-any.whl", hash = "sha256:d4dfea7394d7662edac3831432b349b2afac984e0d0bc4bdb611ec1f3fc16318"}, + {file = "pytube-11.0.1.tar.gz", hash = "sha256:47643a6ff553cbc4d6be748ff14c9c45f79984e15005adff25d62b18110abe43"}, +] +redis = [ + {file = "redis-3.5.3-py2.py3-none-any.whl", hash = "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24"}, + {file = "redis-3.5.3.tar.gz", hash = "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2"}, +] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, @@ -706,6 +804,10 @@ regex = [ {file = "regex-2021.10.23-cp39-cp39-win_amd64.whl", hash = "sha256:0f7552429dd39f70057ac5d0e897e5bfe211629652399a21671e53f2a9693a4e"}, {file = "regex-2021.10.23.tar.gz", hash = "sha256:f3f9a91d3cc5e5b0ddf1043c0ae5fa4852f18a1c0050318baf5fc7930ecc1f9c"}, ] +requests = [ + {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, + {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -723,6 +825,10 @@ typing-extensions = [ {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, ] +urllib3 = [ + {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, + {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"}, +] uvloop = [ {file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"}, {file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30ba9dcbd0965f5c812b7c2112a1ddf60cf904c1c160f398e7eed3a6b82dcd9c"}, diff --git a/pyproject.toml b/pyproject.toml index 2380df1..8c377dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [tool.poetry] -name = "christmasbot" -version = "0.1.0" -description = "" -authors = ["Your Name "] +name = "tunebot" +version = "1.0.0" +description = "A very configurable Discord radio" +authors = ["StrNophix ", "Matthww "] license = "GPL-v3.0" [tool.poetry.dependencies] @@ -15,6 +15,9 @@ aioredis = "^2.0.0" [tool.poetry.dev-dependencies] black = {version = "^21.9b0", allow-prereleases = true} +redis = "^3.5.3" +aiotube = "^1.3.5" +requests = "^2.26.0" pre-commit = "^2.15.0" [build-system] diff --git a/scripts/playlist_to_redis.py b/scripts/playlist_to_redis.py new file mode 100644 index 0000000..b5fecd7 --- /dev/null +++ b/scripts/playlist_to_redis.py @@ -0,0 +1,21 @@ +import json +from aiotube import Playlist +import redis +import sys + +if len(sys.argv) < 2: + raise Exception("Expected path to file as argument") + +config_path = sys.argv[1] + +config = json.load(open("config.json", "r", encoding="utf-8")) +redis_prefix = config["redis_prefix"] +redis_client = redis.from_url(config["redis_url"]) + +file = open(config_path, "r") +for line in file: + playlist = Playlist(line) + for vid in playlist.videos(): + yt_url = vid.url + redis_client.sadd(f"{redis_prefix}:playlist", yt_url) + print(yt_url) \ No newline at end of file diff --git a/scripts/playlists/.gitkeep b/scripts/playlists/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/utils/classes.py b/utils/classes.py index 7e25c90..5c90b02 100644 --- a/utils/classes.py +++ b/utils/classes.py @@ -1,10 +1,10 @@ from typing import Dict from discord.ext.commands import Cog -from bot import ChristmasBot +from bot import TuneBot class BaseCog(Cog): - def __init__(self, bot: ChristmasBot) -> None: + def __init__(self, bot: TuneBot) -> None: self.bot = bot slash_descriptions: Dict[str, str] = self.bot.config["slash_descriptions"]