Skip to content

Commit e1ccf04

Browse files
authored
Merge pull request #1 from RB387/dev
Added first version of bot
2 parents e21c351 + 02e0a0a commit e1ccf04

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1312
-3
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DISCORD_TOKEN=

.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ dist/
1414
downloads/
1515
eggs/
1616
.eggs/
17-
lib/
18-
lib64/
1917
parts/
2018
sdist/
2119
var/
@@ -102,7 +100,6 @@ celerybeat.pid
102100
*.sage.py
103101

104102
# Environments
105-
.env
106103
.venv
107104
env/
108105
venv/
@@ -127,3 +124,5 @@ dmypy.json
127124

128125
# Pyre type checker
129126
.pyre/
127+
128+
.idea

Dockerfile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
FROM python:3.8-alpine
2+
3+
COPY . ./
4+
5+
# Install build dependencies
6+
RUN apk update && apk add --no-cache --virtual .build-deps \
7+
build-base \
8+
libffi-dev \
9+
libsodium-dev
10+
11+
# Install dependencies
12+
RUN apk update && apk add --no-cache \
13+
ca-certificates \
14+
ffmpeg \
15+
opus-dev \
16+
libffi \
17+
libsodium \
18+
gcc
19+
20+
# Install pip dependencies
21+
RUN pip3 install --no-cache-dir -r requirements.txt
22+
23+
# Clean up build dependencies
24+
RUN apk del .build-deps
25+
26+
ENTRYPOINT ["python", "main.py"]

README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Python Discord Music Bot
2+
Easy to extend and support
3+
4+
## Supported commands
5+
```
6+
!play [url or name] - play song from any stream/video or youtube search
7+
!queue - current bot song queue
8+
!pause - pause current song
9+
!resume - resume paused song
10+
!skip - skip current song
11+
!clear - clear bot queue
12+
!message-clean - clear bot messages
13+
!studio21 - play radio studio21
14+
!21queue - show studio21 queue
15+
```
16+
17+
## Background queue tasks
18+
Just add queue in config.toml
19+
```python
20+
bot: DiscordBot
21+
22+
async def task():
23+
print('done in background')
24+
25+
await bot.add_task('my_queue', task)
26+
```
27+
28+
## Configuration
29+
All bot configuration in config.toml
30+
The only exception is secrets. They must be set in environment or in file .env:
31+
```
32+
DISCORD_TOKEN -- bot token
33+
```
34+
35+
## MacOS Installation
36+
```
37+
brew install ffmpeg
38+
pip intall -r requirements.txt
39+
```
40+
41+
## Run
42+
### Docker
43+
```
44+
docker build -t discord-music-bot .
45+
docker run discord-music-bot
46+
```
47+
### Local
48+
```
49+
python main.py
50+
```
51+
52+
## Tests
53+
```
54+
pip install -r test-requirements.txt
55+
pytest tests/
56+
```
57+
58+
## TODO
59+
* Write tests on bot business logic
60+
* Add loop queue

config.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
language = "en"
2+
3+
[common]
4+
messages_ttl = "5"
5+
playlist_queue = "playlist"
6+
7+
[bot]
8+
command_prefix = "!"
9+
10+
[[bot.queues]]
11+
name = "playlist"
12+
13+
[ydl]
14+
format = "bestaudio/best"
15+
noplaylist = "true"
16+
source_address = "0.0.0.0"
17+
default_search = "auto"
18+
19+
[ffmpeg]
20+
before_options = "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 -nostdin"
21+
options = "-vn"
22+
23+
[logger]
24+
level = "INFO"
25+
26+
[response]
27+
colour = 7506394
28+
footer_img = "https://i.imgur.com/gFHBoZA.png"
29+
footer_text = "https://github.com/RB387/py-discord-music-bot"
30+
author_url = "https://github.com/RB387/py-discord-music-bot"

constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from pathlib import Path
2+
3+
CONFIG_PATH = Path(__file__).parent / 'config.toml'
4+
TEMPLATES_PATH = Path(__file__).parent / 'templates'

lib/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .commads import * # noqa
2+
from .events import * # noqa

lib/app.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from typing import Type
2+
3+
from lib.core.bot import DiscordBot
4+
from lib.core.injector import DependencyInjector
5+
from lib.core.logger import Logger
6+
from lib.core.router import Router, router as default_router
7+
8+
9+
class App:
10+
def __init__(
11+
self,
12+
injector: DependencyInjector,
13+
bot_cls: Type[DiscordBot] = DiscordBot,
14+
):
15+
16+
self._injector = injector
17+
self._bot = injector.inject(bot_cls)
18+
self._logger = injector.inject(Logger)
19+
self._routers = [default_router]
20+
21+
def run(self):
22+
self._setup_routes()
23+
24+
self._bot.listen('on_connect')(self._injector.connect)
25+
self._bot.listen('on_disconnect')(self._injector.disconnect)
26+
27+
self._logger.info('Running bot...')
28+
self._bot.run()
29+
30+
def add_router(self, router: Router):
31+
self._routers.append(router)
32+
33+
def _setup_routes(self):
34+
for router in self._routers:
35+
routes = router.get_routes()
36+
37+
for event in routes.events:
38+
handler = self._injector.inject(event.handler)
39+
self._bot.listen(event.name)(handler.handle)
40+
41+
for command in routes.commands:
42+
handler = self._injector.inject(command.handler)
43+
self._bot.command(name=command.name)(handler.handle)

lib/commads/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from .clear import PlaylistCleaner
2+
from .message_clear import MessageCleaner
3+
from .pause import Pause
4+
from .play import Player
5+
from .queue import QueueStatus
6+
from .resume import Resume
7+
from .skip import Skip
8+
from .studio21 import Studio21Player, Studio21QueueStatus

lib/commads/clear.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from dataclasses import dataclass
2+
3+
from discord.ext.commands import Context
4+
5+
from lib.core import ClientProtocol, router
6+
from lib.emoji import Emoji
7+
from lib.messenger import Messenger
8+
from lib.playlist import Playlist
9+
10+
11+
@router.command('clear')
12+
@dataclass
13+
class PlaylistCleaner(ClientProtocol):
14+
playlist: Playlist
15+
messenger: Messenger
16+
17+
async def handle(self, ctx: Context):
18+
await self.messenger.react(ctx, Emoji.OK_HAND)
19+
await self.playlist.clear()

0 commit comments

Comments
 (0)