diff --git a/.trunk/configs/.isort.cfg b/.trunk/configs/.isort.cfg new file mode 100644 index 0000000..b9fb3f3 --- /dev/null +++ b/.trunk/configs/.isort.cfg @@ -0,0 +1,2 @@ +[settings] +profile=black diff --git a/.trunk/configs/ruff.toml b/.trunk/configs/ruff.toml new file mode 100644 index 0000000..f5a235c --- /dev/null +++ b/.trunk/configs/ruff.toml @@ -0,0 +1,5 @@ +# Generic, formatter-friendly config. +select = ["B", "D3", "E", "F"] + +# Never enforce `E501` (line length violations). This should be handled by formatters. +ignore = ["E501"] diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 73b11de..4a7abcb 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -7,7 +7,7 @@ cli: plugins: sources: - id: trunk - ref: v1.4.4 + ref: v1.4.5 uri: https://github.com/trunk-io/plugins # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) runtimes: @@ -18,18 +18,18 @@ runtimes: lint: enabled: - actionlint@1.6.27 - - bandit@1.7.7 - - black@24.2.0 + - bandit@1.7.8 + - black@24.3.0 - codespell - - checkov@3.2.32 + - checkov@3.2.48 - git-diff-check - isort@5.13.2 - pylint - markdownlint@0.39.0 - prettier@3.2.5 - - ruff@0.3.1 - - trivy@0.49.1 - - trufflehog@3.68.5 + - ruff@0.3.4 + - trivy@0.50.1 + - trufflehog@3.71.0 - yamllint@1.35.1 actions: disabled: diff --git a/bot.py b/bot.py index cfef22a..d2bb2cd 100644 --- a/bot.py +++ b/bot.py @@ -34,7 +34,7 @@ import PyPDF2 import requests import spotipy import tiktoken -from discord.ext import commands +from discord.ext import commands, tasks from spotipy.oauth2 import SpotifyClientCredentials import yt_dlp @@ -197,13 +197,10 @@ async def on_ready(): logger.debug("%s has connected to Discord!", client.user) await client.change_presence(activity=discord.Game(name="Axe Throwing Darts")) await client.tree.sync() - await check() + check_data.start() @client.event -# trunk-ignore(pylint/R0915) -# trunk-ignore(pylint/R0914) -# trunk-ignore(pylint/R0912) async def on_message(message): """ Handle incoming messages in a Discord server, perform various @@ -409,8 +406,6 @@ async def disconnect(ctx): await voice_client.disconnect() -# trunk-ignore(pylint/R0915) -# trunk-ignore(pylint/R0912) async def play(ctx, zamawial=None, arg=None): """ Play a music file, retrieve metadata about the file, and send a @@ -439,11 +434,13 @@ async def play(ctx, zamawial=None, arg=None): if MUZYKA["queue"]: file_to_play = MUZYKA["queue"].pop() zamawial = MUZYKA["requester"].pop() + logger.info("Muzyka z listy zamówień") else: index = random.randint(0, len(music_file_list) - 1) file_to_play = music_file_list[index] + logger.info("Muzyka losowo") - logger.debug(file_to_play) + logger.info(file_to_play) metadata = eyed3.load(file_to_play) query = None temp = file_to_play.split(SEPARATOR_FILE_PATH)[-1] @@ -504,89 +501,96 @@ async def archive_channel(channel_no): path_newfile = f"{LOGSTORE}channeldump_{channel_no}_{datetime.now()}.json" new_data = [] for message in messages: - pass + new_data.append(message) with open(path_newfile, "x", encoding=ENCODING) as new_file: new_file.seek(0) json.dump(new_data, new_file, indent=4) -async def check(): - """Funkcja sprawdzająca czy grać następny kawałek.""" - last_spontaneous_call = datetime.now() - while True: - tdelta = datetime.now() - last_spontaneous_call - tdelta = tdelta.total_seconds() - if tdelta > 34000: - channel = client.get_channel(1062047571557744721) - last_spontaneous_call = datetime.now() - with channel.typing(): - message = get_random_cyclic_message() - await channel.send(message) - # trunk-ignore(codespell/misspelled) - # TODO: dlaczego sie tu wypierdala - if client.voice_clients: - voice_client = client.voice_clients[0] - if voice_client.is_connected(): - while MUZYKA["playing"] and voice_client.is_connected(): - if ( - voice_client - and not voice_client.is_playing() - and not voice_client.is_paused() - ): - await play(MUZYKA["ctx"], MUZYKA["requester"]) - await asyncio.sleep(0.1) - if os.path.getsize(LOGFILE) > 600000: - shutil.copyfile(LOGFILE, f"{LOGSTORE}discord{datetime.now()}") - logger.info("Log rollover") - handler.doRollover() +@tasks.loop(seconds=1) +async def check_music(): + """ + This Python function continuously checks for music playback in a voice client and plays music if + conditions are met. + """ + if client.voice_clients: + voice_client = client.voice_clients[0] + if voice_client.is_connected(): + while MUZYKA["playing"] and voice_client.is_connected(): + if ( + voice_client + and not voice_client.is_playing() + and not voice_client.is_paused() + ): + await play(MUZYKA["ctx"], MUZYKA["requester"]) + await asyncio.sleep(1) - if os.path.getsize(MEMORY_FIVE_MUZYKA) > 300000: - channel = client.get_channel(1062047571557744721) - await channel.send( - "*Conjurer porządkuje bar, wypala szklanki do czysta miotaczem płomieni ze swojej zbroi i ogólnie wygląda na zajętego....*" - ) - with channel.typing(): - path_newfile = ( - f"{LOGSTORE}{MEMORY_FIVE_MUZYKA[:-4]}{datetime.now()}.json" - ) - with open( - MEMORY_FIVE_MUZYKA, "r+", encoding=ENCODING - ) as file_music_memory: - with open(path_newfile, "x", encoding=ENCODING) as new_file: - # First we load existing data into a dict. - file_data = json.load(file_music_memory) - new_data = [] - new_data.append(file_data[0]) - new_data.extend(file_data[:-20]) - file_music_memory.seek(0) - # convert back to json. - new_file.seek(0) - json.dump(new_data, file_music_memory, indent=4) - json.dump(file_data, new_file, indent=4) - await channel.send( - "*Przeciąga się za barem* No dobra - porobione to można dalej pi... *Zauważa spojrzenie Hammera* ...sać powieści o naszym wspaniałym barze SZEFIE!" - ) - if os.path.getsize(MEMORY_FIVE_SIARA) > 300000: - path_newfile = "{LOGSTORE}{MEMORY_FIVE_SIARA[:-4]}{datetime.now()}.json" - await channel.send( - "*Conjurer porządkuje bar, ścina lekkim laserem pulsacyjnym powierzchnie baru o grubości kilku mikronów i ogólnie wygląda na zajętego....*" - ) - with open(MEMORY_FIVE_SIARA, "r+", encoding=ENCODING) as file: + +@tasks.loop(minutes=2) +async def check_data(): + """ + The function `check_data` periodically checks for conditions to send messages and manage log files + in a Discord channel. + """ + last_spontaneous_call = datetime.now() + tdelta = datetime.now() - last_spontaneous_call + tdelta = tdelta.total_seconds() + if tdelta > 34000: + channel = client.get_channel(1062047571557744721) + last_spontaneous_call = datetime.now() + with channel.typing(): + message = get_random_cyclic_message() + await channel.send(message) + # trunk-ignore(codespell/misspelled) + # TODO: dlaczego sie tu wypierdala + if os.path.getsize(LOGFILE) > 600000: + shutil.copyfile(LOGFILE, f"{LOGSTORE}discord{datetime.now()}") + logger.info("Log rollover") + handler.doRollover() + + if os.path.getsize(MEMORY_FIVE_MUZYKA) > 300000: + channel = client.get_channel(1062047571557744721) + await channel.send( + "*Conjurer porządkuje bar, wypala szklanki do czysta miotaczem płomieni ze swojej zbroi i ogólnie wygląda na zajętego....*" + ) + with channel.typing(): + path_newfile = f"{LOGSTORE}{MEMORY_FIVE_MUZYKA[:-4]}{datetime.now()}.json" + with open(MEMORY_FIVE_MUZYKA, "r+", encoding=ENCODING) as file_music_memory: with open(path_newfile, "x", encoding=ENCODING) as new_file: # First we load existing data into a dict. - file_data = json.load(file) + file_data = json.load(file_music_memory) new_data = [] new_data.append(file_data[0]) new_data.extend(file_data[:-20]) - file.seek(0) - new_file.seek(0) + file_music_memory.seek(0) # convert back to json. - json.dump(new_data, file, indent=4) + new_file.seek(0) + json.dump(new_data, file_music_memory, indent=4) json.dump(file_data, new_file, indent=4) await channel.send( - "*Przeciąga się za barem* No dobra - porobione to można dalej pi... *Zauważa spojrzenie Hammera* eprzyć o głupotach z klientami... Szefie... *Bierze 'ukradkowy' łyk z piersiówki*" + "*Przeciąga się za barem* No dobra - porobione to można dalej pi... *Zauważa spojrzenie Hammera* ...sać powieści o naszym wspaniałym barze SZEFIE!" ) - await asyncio.sleep(60) + if os.path.getsize(MEMORY_FIVE_SIARA) > 300000: + path_newfile = "{LOGSTORE}{MEMORY_FIVE_SIARA[:-4]}{datetime.now()}.json" + await channel.send( + "*Conjurer porządkuje bar, ścina lekkim laserem pulsacyjnym powierzchnie baru o grubości kilku mikronów i ogólnie wygląda na zajętego....*" + ) + with open(MEMORY_FIVE_SIARA, "r+", encoding=ENCODING) as file: + with open(path_newfile, "x", encoding=ENCODING) as new_file: + # First we load existing data into a dict. + file_data = json.load(file) + new_data = [] + new_data.append(file_data[0]) + new_data.extend(file_data[:-20]) + file.seek(0) + new_file.seek(0) + # convert back to json. + json.dump(new_data, file, indent=4) + json.dump(file_data, new_file, indent=4) + await channel.send( + "*Przeciąga się za barem* No dobra - porobione to można dalej pi... *Zauważa spojrzenie Hammera* eprzyć o głupotach z klientami... Szefie... *Bierze 'ukradkowy' łyk z piersiówki*" + ) + await asyncio.sleep(60) async def get_random_cyclic_message(): @@ -599,9 +603,6 @@ async def get_random_cyclic_message(): return cyclic_words[messnum][0] -# trunk-ignore(pylint/R0914) -# trunk-ignore(pylint/R0913) -# trunk-ignore(pylint/R0915) async def handle_response(prompt, vykidailo, bartender, history, username, music): """ Handle responses by appending them to a history, use OpenAI to @@ -734,8 +735,6 @@ async def handle_response(prompt, vykidailo, bartender, history, username, music return result, MESSAGE_TABLE -# trunk-ignore(pylint/R0914) -# trunk-ignore(pylint/R0915) async def get_file(ctx, source, link): """ Take in three parameters: "ctx" (context), @@ -753,7 +752,7 @@ async def get_file(ctx, source, link): """ item_id = None item_type = None - file_list = {} + file_list = [] if source == "Spotify": dir_path = None item_type, item_id = spotify.parse_spotify_url(link) @@ -915,9 +914,6 @@ async def get_stats(ctx, history_limit): yield name, how_many -# trunk-ignore(pylint/R0914) -# trunk-ignore(pylint/R0915) -# trunk-ignore(pylint/R0912) async def wyszukaj(ctx, how_many=0, slowa_kluczowe=None): """ Take in a context object and an optional integer parameter "how_many" and perform search @@ -1135,8 +1131,6 @@ async def dej_co_z_jutuba(ctx): description="Jeśli nie wiesz jak użyć tej komendy to nawet nie próbuj", guild=discord.Object(id=664789470779932693), ) -# trunk-ignore(pylint/R0914) -# trunk-ignore(pylint/R0912) async def update_banlist(ctx): """ Update a banlist in a Discord guild from preprovided list in channel. @@ -1280,6 +1274,7 @@ async def graj_muzyko(ctx): """ logger.info("Press play on tape") + check_music.start() async with ctx.typing(): global MUZYKA # pylint: disable=global-variable-not-assigned MUZYKA["playing"] = True @@ -1314,6 +1309,7 @@ async def cisza(ctx): MUZYKA["queue"].pop() MUZYKA["requester"].pop() logger.info("Stop completed") + check_music.stop() @client.hybrid_command( @@ -1650,8 +1646,6 @@ async def get_image_stable_diffusion(ctx): description="Gra muzyke wyszukana na bazie tematow konwersacji na kanale NZ", guild=discord.Object(id=664789470779932693), ) -# trunk-ignore(pylint/R0912) -# trunk-ignore(pylint/R0915) async def zagraj_muzyke_mego_ludu(ctx): """ Play completeley random playlist based on messaging history. diff --git a/mp3_list.service.py b/mp3_list.service.py new file mode 100644 index 0000000..511b049 --- /dev/null +++ b/mp3_list.service.py @@ -0,0 +1,35 @@ +from pathlib import Path, PurePath +from platform import uname +from sys import platform +MUSIC_FOLDER = "" +if platform in ("linux", "linux2"): + SEPARATOR_FILE_PATH = "/" + if "microsoft-standard" in uname().release: + LOGFILE = "/home/mtuszowski/conjurer/discord_mus_service.log" + MUSIC_FOLDER = "/mnt/g/Muzyka/" + NETRC_FILE = "/home/mtuszowski/.netrc" + LOGSTORE = "/home/mtuszowski/conjurer/logs/" + ENCODING = "utf-8" + GRAPHICS_PATH = "/home/mtuszowski/conjurer/Conjurer_graphics/" + + else: + LOGFILE = "/home/pi/Conjurer/discord_mus_service.log" + MEMORY_FIVE_SIARA = "/home/pi/Conjurer/pamiec.json" + SYSTEM_GPT_SETTINGS = "/home/pi/Conjurer/system_gpt_settings.json" + MEMORY_FIVE_MUZYKA = "/home/pi/Conjurer/pamiec_muzyki.json" + MUSIC_FOLDER = "/home/pi/RetroPie/mp3/" + SETTINGS_FILE = "/home/pi/Conjurer/settings.json" + NETRC_FILE = "/home/pi/.netrc" + LOGSTORE = "/home/pi/RetroPie/logs/" + ACCIDENT_LOG = "/home/pi/Conjurer/accident_log.json" + ENCODING = "utf-8" + GRAPHICS_PATH = "/home/pi/RetroPie/Conjurer_graphics/" + DIR_PATH_SADOX = "/home/pi/RetroPie/Fansadox/" + +music_file_list = [] +for mp3_item in Path.glob(Path(MUSIC_FOLDER), "**/*.mp3"): + temp_music_file = mp3_item.as_posix() + if platform == "win32": + temp_music_file = temp_music_file.replace("/", "\\") + music_file_list.append(temp_music_file) +