diff --git a/Dockerfile b/Dockerfile index 9402bbd..65c00a5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ -# Python 3.7 -FROM python:3.7 +FROM python:3.7-slim -# Update system -RUN apt-get -y update -RUN apt-get -y upgrade # Install ffmpeg -RUN apt-get install -y --no-install-recommends ffmpeg +RUN apt-get -y update && \ + apt-get install -y --no-install-recommends ffmpeg && \ + apt-get autoremove -y && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* # All source code WORKDIR /src @@ -14,11 +14,10 @@ WORKDIR /src COPY requirements.txt . # Install all dependencies. -RUN pip install -r requirements.txt +RUN pip install --only-binary all --no-cache-dir -r requirements.txt # Copy PlexBot over to src. COPY PlexBot/ PlexBot # Run the bot -# CMD ["python", "-OO", "-m", "PlexBot"] -CMD ["python", "-m", "PlexBot"] +CMD ["python", "-OO", "-m", "PlexBot"] diff --git a/Jenkinsfile b/Jenkinsfile index 7f28ee8..dce5b1e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -49,7 +49,7 @@ pipeline { steps { sh ''' source /var/lib/jenkins/miniconda3/etc/profile.d/conda.sh conda activate ${BUILD_TAG} - docker build . + python deploy/build.py ''' } post { @@ -58,6 +58,7 @@ pipeline { archiveArtifacts (allowEmptyArchive: true, artifacts: 'dist/*whl', fingerprint: true) + // sh 'python deploy/push.py' } } } diff --git a/PlexBot/__init__.py b/PlexBot/__init__.py index e3b062f..c2ffd18 100644 --- a/PlexBot/__init__.py +++ b/PlexBot/__init__.py @@ -8,7 +8,9 @@ import yaml FORMAT = "%(asctime)s %(levelname)s: [%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s" logging.basicConfig(format=FORMAT) -logger = logging.getLogger("PlexBot") +root_log = logging.getLogger() +plex_log = logging.getLogger("Plex") +bot_log = logging.getLogger("Bot") def load_config(filename: str) -> Dict[str, str]: @@ -20,7 +22,7 @@ def load_config(filename: str) -> Dict[str, str]: with open(filename, "r") as f: config = yaml.safe_load(f) except FileNotFoundError: - logging.fatal("Configuration file not found.") + root_log.fatal("Configuration file not found.") sys.exit(-1) # Convert str level type to logging constant @@ -31,7 +33,9 @@ def load_config(filename: str) -> Dict[str, str]: "ERROR": logging.ERROR, "CRITICAL": logging.CRITICAL, } - level = config["general"]["log_level"] - config["general"]["log_level"] = levels[level.upper()] + + config["root"]["log_level"] = levels[config["root"]["log_level"].upper()] + config["plex"]["log_level"] = levels[config["plex"]["log_level"].upper()] + config["discord"]["log_level"] = levels[config["discord"]["log_level"].upper()] return config diff --git a/PlexBot/__main__.py b/PlexBot/__main__.py index e14e580..e72e7b1 100644 --- a/PlexBot/__main__.py +++ b/PlexBot/__main__.py @@ -16,12 +16,14 @@ TOKEN = config["discord"]["token"] BASE_URL = config["plex"]["base_url"] PLEX_TOKEN = config["plex"]["token"] LIBRARY_NAME = config["plex"]["library_name"] -LOG_LEVEL = config["general"]["log_level"] # Set appropiate log level -logger = logging.getLogger("PlexBot") -logging.basicConfig(format=FORMAT) -logger.setLevel(LOG_LEVEL) +root_log = logging.getLogger() +plex_log = logging.getLogger("Plex") +bot_log = logging.getLogger("Bot") + +plex_log.setLevel(config["plex"]["log_level"]) +bot_log.setLevel(config["discord"]["log_level"]) bot = Bot(command_prefix=BOT_PREFIX) bot.add_cog(General(bot)) diff --git a/PlexBot/__version__.py b/PlexBot/__version__.py new file mode 100644 index 0000000..fe96268 --- /dev/null +++ b/PlexBot/__version__.py @@ -0,0 +1 @@ +VERSION = "0.0.4" diff --git a/PlexBot/bot.py b/PlexBot/bot.py index e7db3f8..c71e64a 100644 --- a/PlexBot/bot.py +++ b/PlexBot/bot.py @@ -12,7 +12,9 @@ from fuzzywuzzy import fuzz from plexapi.exceptions import Unauthorized from plexapi.server import PlexServer -logger = logging.getLogger("PlexBot") +root_log = logging.getLogger() +plex_log = logging.getLogger("Plex") +bot_log = logging.getLogger("Bot") class General(commands.Cog): @@ -25,7 +27,7 @@ class General(commands.Cog): await ctx.send(f"Stopping upon the request of {ctx.author.mention}") await self.bot.close() - logger.info(f"Stopping upon the request of {ctx.author.mention}") + bot_log.info(f"Stopping upon the request of {ctx.author.mention}") @command() async def cleanup(self, ctx, limit=250): @@ -55,10 +57,11 @@ class Plex(commands.Cog): try: self.pms = PlexServer(self.base_url, self.plex_token) except Unauthorized: - logger.fatal("Invalid Plex token, stopping...") + plex_log.fatal("Invalid Plex token, stopping...") raise Unauthorized("Invalid Plex token") self.music = self.pms.library.section(self.library_name) + plex_log.debug(f"Connected to plex library: {self.library_name}") self.vc = None self.current_track = None @@ -69,7 +72,7 @@ class Plex(commands.Cog): self.bot.loop.create_task(self._audio_player_task()) - logger.info("Started bot successfully") + bot_log.info("Started bot successfully") def _search_tracks(self, title): tracks = self.music.searchTracks() @@ -93,8 +96,7 @@ class Plex(commands.Cog): self.vc.play(audio_stream, after=self._toggle_next) - logger.debug(f"Playing {self.current_track.title}") - logger.debug(f"URL: {track_url}") + plex_log.debug(f"{self.current_track.title} - URL: {track_url}") embed, f = self._build_embed(self.current_track) self.np_message_id = await self.ctx.send(embed=embed, file=f) @@ -150,6 +152,8 @@ class Plex(commands.Cog): # Point to file attached with ctx object. embed.set_thumbnail(url="attachment://image0.png") + bot_log.debug(f"Built embed for {track.title}") + return embed, f @command() @@ -159,6 +163,7 @@ class Plex(commands.Cog): if not len(args): await ctx.send(f"Usage: {self.bot_prefix}play TITLE_OF_SONG") + bot_log.debug("Failed to play, invalid usage") return title = " ".join(args) @@ -167,19 +172,23 @@ class Plex(commands.Cog): # Fail if song title can't be found if not track: await ctx.send(f"Can't find song: {title}") + bot_log.debug(f"Failed to play, can't find song - {title}") return + # Fail if user not in vc elif not ctx.author.voice: await ctx.send("Join a voice channel first!") + bot_log.debug("Failed to play, requester not in voice channel") return # Connect to voice if not already if not self.vc: self.vc = await ctx.author.voice.channel.connect() - logger.debug("Connected to vc.") + bot_log.debug("Connected to vc.") # Specific add to queue message if self.vc.is_playing(): + bot_log.debug(f"Added to queue - {title}") embed, f = self._build_embed(track, t="queue") await ctx.send(embed=embed, file=f) @@ -193,34 +202,45 @@ class Plex(commands.Cog): await self.vc.disconnect() self.vc = None self.ctx = None + bot_log.debug("Stopped") await ctx.send(":stop_button: Stopped") @command() async def pause(self, ctx): if self.vc: self.vc.pause() + bot_log.debug("Paused") await ctx.send(":play_pause: Paused") @command() async def resume(self, ctx): if self.vc: self.vc.resume() + bot_log.debug("Resumed") await ctx.send(":play_pause: Resumed") @command() async def skip(self, ctx): - logger.debug("Skip") + bot_log.debug("Skip") if self.vc: self.vc.stop() + bot_log.debug("Skipped") self._toggle_next() @command() async def np(self, ctx): if self.current_track: embed, f = self._build_embed(self.current_track) - await ctx.send(embed=embed, file=f) + bot_log.debug("Now playing") + if self.np_message_id: + await self.np_message_id.delete() + bot_log("Deleted old np status") + + bot_log("Created np status") + self.np_message_id = await ctx.send(embed=embed, file=f) @command() async def clear(self, ctx): self.play_queue = asyncio.Queue() + bot_log.debug("Cleared queue") await ctx.send(":boom: Queue cleared.") diff --git a/deploy/build.py b/deploy/build.py new file mode 100644 index 0000000..78c9326 --- /dev/null +++ b/deploy/build.py @@ -0,0 +1,8 @@ +import os +import sys + +sys.path.append("PlexBot") + +from __version__ import VERSION + +sys.exit(os.system(f"docker build -t jarulsamy/plex-bot:{VERSION} .")) diff --git a/deploy/push.py b/deploy/push.py new file mode 100755 index 0000000..98fc956 --- /dev/null +++ b/deploy/push.py @@ -0,0 +1,8 @@ +import os +import sys + +sys.path.append("PlexBot") + +from __version__ import VERSION + +sys.exit(os.system(f"docker push jarulsamy/plex-bot:{VERSION}")) diff --git a/requirements.txt b/requirements.txt index b231446..044fb46 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ discord.py==1.3.4 PlexAPI==4.0.0 fuzzywuzzy==0.18.0 -python-Levenshtein==0.12.0 pynacl==1.4.0 ffmpeg==1.4 PyYAML==5.3.1 diff --git a/sample-config.yaml b/sample-config.yaml index 22273fd..0b2f204 100644 --- a/sample-config.yaml +++ b/sample-config.yaml @@ -1,12 +1,13 @@ -general: - # Options: debug, info, warning, error, critical +root: log_level: "info" discord: prefix: "?" token: "" + log_level: "debug" plex: base_url: "" token: "" library_name: "" + log_level: "debug"