Skip to content

Commit

Permalink
Merge pull request #70 from clockwinder/containerize
Browse files Browse the repository at this point in the history
Containerize
  • Loading branch information
clockwinder authored Dec 21, 2024
2 parents 58ff6a4 + aaa62f9 commit c7d7a24
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 140 deletions.
27 changes: 27 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# .dockerignore

# Git
.git
.gitignore
.gitattributes

# Docker
docker-compose.yaml
Dockerfile
.docker
.dockerignore

# Cached Files #
*.pyc
**/__pycache__

# Documentation
README.md

#User Data
userconfig.yaml
exampleconfig.yaml
/user_config

# Backup
**/config.py.bak
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,15 @@ Thumbs.db
#################
private.py
config.py
config.py.bak
userconfig.yaml
exampleconfig.yaml
/user_config

# Directories #
###############
ffmpeg-2021-11-22/
# Docker
docker-compose.yaml
#Dockerfile
.docker

# Cached Files #
################
Expand Down
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM python:3.12.5-alpine

WORKDIR /rainwavediscordbot

COPY ./requirements.txt /rainwavediscordbot
RUN pip install -r requirements.txt
RUN apk add ffmpeg
RUN apk add opus

ENV DISCORD_TOKEN=
ENV RAINWAVE_ID=
ENV RAINWAVE_KEY=
ENV LOG_LEVEL="INFO"

COPY . /rainwavediscordbot

CMD [ "python", "./app/rainwavebot.py" ]

#Build command `docker build -t rainwavetest .`
File renamed without changes
72 changes: 72 additions & 0 deletions app/load_config/defaultconfig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
botChannels:
#To restrict which voice channels the bot can use, set below to true.
restrictVoiceChannels: False
#If above is set to true, list allowed channel/s IDs in a list as shown below.
allowedVoiceChannels: [123456789012345678, 987654321098765432]

#To restrict which test channels the bot can receive commands on, set below to true.
restrictTextChannels: False
#If above is set to true, list allowed channel/s IDs in a list as shown below.
allowedTextChannels: [112233445566778899, 998877665544332211]

#If you want the bot to log, login and error info in a channel, set below to True
enableLogChannel: False
#If above is set to true, list your logging channel ID below
logChannel: 246813579024681357

private:
#Discord bot token
discordBotToken: F4K3T0K3N_ikb331nmGsvgHPGAv8jwFV3gKFs9eR.nF4lgje68ZdrEX9aSJ

#Rainwave API ID
rainwaveID: 12345

#Rainwave API Key
rainwaveKey: 12345abcde

dependencies:
#Location of FFMPEG file.
ffmpegLocation: "/usr/bin/ffmpeg"

#Location of opus file.
opusLocation: "/usr/lib/libopus.so.0"

options:
#Change the name of your bot here
botName: "Rain.Wave"

#Change the prefix of your bot here
botPrefix: "rw."

#Enables display of song progress in a numerical style timer e.g. [01:05/01:21]
enableProgressTimes: True

#Enables display of song progress in a graphical manner e.g. ▰▰▰▱▱▱▱▱▱▱▱
enableProgressBar: True

#Allows selection of progress bar style between 1 and 2
#1 is a left to right "fill" style progress bar e.g. ▰▰▰▱▱▱▱▱▱▱▱
#2 is a moving indicator style progress bar e.g. ▱▱▱▰▱▱▱▱▱▱▱
progressBarStyle: 1

#Allows selection of progress bar character length
progressBarLength: 14

#Allows selection of characters which make up the progress bar
#for style 1 ['▰','▱'] or ['▶','▷'] or ['█','░'] is suggested
#for style 2 ['═','╪'] or ['—','⎔'] or ['▬',':radio_button:'] is suggested
progressBarCharacters: ['▰','▱']

#Allows selection of embed sidebar color as an (r, g, b) value.
#You can use https://it-tools.tech/color-converter to generate an rgb color value
embedColor: [24, 135, 210]

#Numer of seconds between refresh of progress bar and timer, can be increased if user is being rate limited.
#Minimum value can never be below 6.
refreshDelay: 6

#If set to `True`, bot will disconnect if no users are present in the bots voice channel.
autoDisconnect: True

#Logging level, can be set to DEBUG, INFO, WARNING, ERROR, CRITICAL. If INFO provides too much info, switch to WARNING
logLevel: "INFO"
63 changes: 63 additions & 0 deletions app/load_config/load_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import os
import shutil
import yaml #Needs to be added to docker setup.
from logger import logger

OS_SLASH = '/'
USER_CONFIG_FOLDER = f"{OS_SLASH}user_config"
DEFAULT_CONFIG_PATH = f"{OS_SLASH}load_config{OS_SLASH}defaultconfig.yaml"
EXAMPLE_CONFIG_PATH = f"{USER_CONFIG_FOLDER}{OS_SLASH}exampleconfig.yaml"
USER_CONFIG_PATH = f"{USER_CONFIG_FOLDER}{OS_SLASH}userconfig.yaml"

EXAMPLE_CONFIG_MESSAGE = "#This is the example config file. It is recreated on every launch.\n#ALL DATA STORED IN THIS FILE WILL BE DELETED!!!"
USER_CONFIG_MESSAGE = "#This is the user config file, changes to this file are persistent.\n#If you delete this file, it will be recreated and all default values will be restored."

class config:
def __init__(self, startingPath):
with open(startingPath+DEFAULT_CONFIG_PATH, "r+") as openDefaultFile:
#NOTE this section fails on windows: `UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 1992: character maps to <undefined>`
#which can be fixed with `encoding='utf-8'` or by adding a windows environmental variable `PYTHONUTF8` with a value of `1`
if os.path.isdir(startingPath+USER_CONFIG_FOLDER) is False: #Create /user_config if it doesn't exist
logger.debug(f"Creating {USER_CONFIG_FOLDER}")
os.mkdir(startingPath+USER_CONFIG_FOLDER)
else:
logger.debug(f"Located {USER_CONFIG_FOLDER}")
logger.debug(f"Config file info: {openDefaultFile}")
if os.path.isfile(startingPath+EXAMPLE_CONFIG_PATH):
logger.debug("Removing old exampleconfig.yaml")
os.remove(startingPath+EXAMPLE_CONFIG_PATH)
logger.debug("Creating exampleconfig.yaml")
with open(startingPath+EXAMPLE_CONFIG_PATH, 'a') as openExampleFile:
openExampleFile.write(f"{EXAMPLE_CONFIG_MESSAGE}\n\n") #write this comment into the first line
shutil.copyfileobj(openDefaultFile, openExampleFile) #append the default file to the example file
logger.debug("Created exampleconfig.yaml")

openDefaultFile.seek(0) #This puts us back at the beginning of openDefaultFile, since we've already indexed to the end

if os.path.isfile(startingPath+USER_CONFIG_PATH):
logger.info("Using previous userconfig.yaml")
else:
logger.debug("Creating userconfig.yaml")
with open(startingPath+USER_CONFIG_PATH, 'a') as openUserFile:
openUserFile.write(f"{USER_CONFIG_MESSAGE}\n\n") #write this comment into the first line
shutil.copyfileobj(openDefaultFile, openUserFile) #append the default file to the user file
logger.info("Created userconfig.yaml")

logger.info("Loading config files")
with open(startingPath+DEFAULT_CONFIG_PATH, "r") as openDefaultFile:
defaultconfig = yaml.safe_load(openDefaultFile)
with open(startingPath+USER_CONFIG_PATH, "r") as openUserFile:
userconfig = yaml.safe_load(openUserFile)
self.config = {}
for section, item in defaultconfig.items():
logger.debug(f"Loading {section} ------")
for key, value in item.items():
try:
if key in userconfig[section]:
logger.debug(f"'{key}' found in userconfig")
self.config[key] = userconfig[section][key]
else:
logger.warning(f"'{key}' not found in user config, default loaded.") #Warn
self.config[key] = value
except:
logger.warning(f"Config section {section} not found") #Warn
17 changes: 17 additions & 0 deletions app/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import logging
import os
from sys import stdout

#Possible log levels are, DEBUG, INFO, WARNING, ERROR, CRITICAL
#Written as debug(), info(), warning(), error() and critical()
logLevel = os.getenv("LOG_LEVEL", default="DEBUG") #Get loglevel environmental from docker

#Set Up logger
logger = logging.getLogger('RWDB_Logger') #Create logger instance with an arbitrary name
logger.setLevel(logLevel) # set logger level
logFormatter = logging.Formatter\
("%(asctime)s %(levelname)-8s %(filename)s:%(funcName)s:%(lineno)d %(message)s", "%Y-%m-%d %H:%M:%S") #What the log string looks like
consoleHandler = logging.StreamHandler(stdout) #set streamhandler to stdout
consoleHandler.setFormatter(logFormatter) #Apply the formatter
logger.addHandler(consoleHandler) #Apply stdout handler to logger
logger.info(f"Logger set to level: {logLevel}")
Loading

0 comments on commit c7d7a24

Please sign in to comment.