diff --git a/.env_default b/.env_default deleted file mode 100644 index c3c92fb..0000000 --- a/.env_default +++ /dev/null @@ -1,15 +0,0 @@ -discord_token='token' -flask_port='5000' -imgflip_username='username' -imgflip_password='password' -openai.api_key='api_key' -upload_phixxy='False' -ftp_server='www.example.com' -ftp_username='username' -ftp_password='password' -ftp_public_html='/home/debian/www.example.com/' -stable_diffusion_ip='disabled' -stable_diffusion_port='7861' -stable_diffusion_user= -stable_diffusion_password= -eleven_labs='api-key' diff --git a/.gitignore b/.gitignore index b52fbef..5637a6d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,4 @@ extensions/ .env databases/ channels/ -.gitignore -cogs/dailies.py -cogs/idlegame.py +.gitignore \ No newline at end of file diff --git a/cogs/chatgpt.py b/cogs/chatgpt.py index 70c3768..3bf0ed8 100644 --- a/cogs/chatgpt.py +++ b/cogs/chatgpt.py @@ -23,6 +23,7 @@ class ChatGPT(commands.Cog): self.folder_setup() self.remind_me_loop.start() self.http_session = self.create_aiohttp_session() + self.dalle_budget = self.get_budget() self.logger = logging.getLogger("bot") self.headers = { 'Content-Type': 'application/json', @@ -51,7 +52,7 @@ class ChatGPT(commands.Cog): self.logger.exception(f"ChatGPT failed to make directories: {e}") def text_cost_calc(self, model, input_tokens, output_tokens): - cost_table = {"gpt-4o-mini":{"input_tokens":0.00000015,"output_tokens":0.0000006}, + cost_table = {"gpt-3.5-turbo":{"input_tokens":0.0000005,"output_tokens":0.0000015}, "gpt-4-turbo-preview":{"input_tokens":0.00001,"output_tokens":0.00003}, "gpt-4-vision-preview":{"input_tokens":0.00001,"output_tokens":0.00003}, "gpt-4o":{"input_tokens":0.000005,"output_tokens":0.000015} @@ -60,6 +61,36 @@ class ChatGPT(commands.Cog): output_cost = cost_table[model]["output_tokens"] * output_tokens cost = input_cost + output_cost return cost + + def get_budget(self): + month = time.strftime("%B") + year = time.strftime("%Y") + key = f"{month}_{year}" + budget_file = f"{self.data_dir}budget.json" + if not os.path.exists(budget_file): + with open(budget_file, "w") as f: + json.dump({key:self.default_budget},f) + with open(budget_file, "r") as f: + budget_dict = json.loads(f.readline()) + if key not in budget_dict: + budget_dict[key] = self.default_budget + with open(budget_file, "w") as f: + json.dump(budget_dict,f) + return self.default_budget + else: + return budget_dict[key] + + def budget_add(self, amount): + month = time.strftime("%B") + year = time.strftime("%Y") + key = f"{month}_{year}" + budget_file = f"{self.data_dir}budget.json" + with open(budget_file, "r") as f: + budget_dict = json.loads(f.readline()) + budget_dict[key] += amount + with open(budget_file, "w") as f: + json.dump(budget_dict,f) + self.dalle_budget += amount def add_cost(self, category: str, cost: float): day = time.strftime("%d") @@ -124,6 +155,28 @@ class ChatGPT(commands.Cog): categories = response_data['results'][0]['categories'] category_scores = response_data['results'][0]['category_scores'] return (flagged, categories, category_scores) + + @commands.command() + async def budget(self, ctx, command=None, budget=None): + try: + if ctx.author.id == self.admin_id: + if command == "add" and budget!= None: + self.budget_add(float(budget)) + await ctx.send(f"Budget increased by {budget}") + elif command == "remove" and budget!= None: + self.budget_add(-float(budget)) + await ctx.send(f"Budget decreased by {budget}") + elif command == "set" and budget!= None: + self.budget_add(float(budget) - self.dalle_budget) + await ctx.send(f"Budget set to {budget}") + else: + await ctx.send(f"The current budget is {self.dalle_budget}") + else: + await ctx.send(f"The current budget is {self.dalle_budget}") + except Exception as e: + self.logger.exception(f"Budget command failed: {e}") + await ctx.send(f"Budget command failed") + @commands.command( name="costs", @@ -234,7 +287,7 @@ class ChatGPT(commands.Cog): user = self.bot.get_user(reminder_dict["user_id"]) return await user.send(reminder_dict["response"]) - async def answer_question(self, topic, model="gpt-4o-mini"): + async def answer_question(self, topic, model="gpt-3.5-turbo"): data = { "model": model, "messages": [{"role": "user", "content": topic}] @@ -259,25 +312,6 @@ class ChatGPT(commands.Cog): self.logger.exception("Error occurred in answer_question") return "Error occurred in answer_question" - @commands.command() - async def translate(self, ctx): - if ctx.message.attachments: - attachment = ctx.message.attachments[0] # assuming only one attachment - await attachment.save(self.working_dir + '/' + attachment.filename) - - with open(self.working_dir + '/' + attachment.filename, 'r') as file: - text = file.read() - question = f"Translate the following text to english: {text}" - # Now text contains the content of the downloaded file - translated_text = await self.answer_question(question) - # Save the translated text to a new file - with open(f'{self.working_dir}/translated_text.txt', 'w') as new_file: - new_file.write(translated_text) - - # Send the text file as an attachment - file = discord.File(f'{self.working_dir}/translated_text.txt') - await ctx.send(file=file) - @commands.command( description="Personality", @@ -368,6 +402,19 @@ class ChatGPT(commands.Cog): chunks = [answer[i:i+1999] for i in range(0, len(answer), 1999)] for chunk in chunks: await ctx.send(chunk) + + @commands.command( + description="Question GPT4", + help="Ask GPT4 a question. Usage: !question_gpt4 (question)", + brief="Get an answer" + ) + async def question_gpt4(self, ctx): + await ctx.send("One moment, let me think...") + question = ctx.message.content.split(" ", maxsplit=1)[1] + answer = await self.answer_question(question, "gpt-4o") + chunks = [answer[i:i+1999] for i in range(0, len(answer), 1999)] + for chunk in chunks: + await ctx.send(chunk) async def dalle_api_call(self, prompt: str, model: str="dall-e-2", quality: str="standard", size: str="1024x1024") -> tuple: if self.dalle_budget <= await self.get_monthly_cost(): @@ -635,7 +682,7 @@ class ChatGPT(commands.Cog): message = ctx.content[0] data = { - "model": "gpt-4o-mini", + "model": "gpt-3.5-turbo", "messages": [{"role": "system", "content": system_msg}, {"role": "user", "content": message}] } diff --git a/cogs/inky_phat.py b/cogs/inky_phat.py index 9878834..deed2b2 100644 --- a/cogs/inky_phat.py +++ b/cogs/inky_phat.py @@ -146,6 +146,4 @@ class InkyScreen(commands.Cog): async def setup(bot): - #await bot.add_cog(InkyScreen(bot)) - #Temporarily disable as this is probably unused for everyone including me - pass \ No newline at end of file + await bot.add_cog(InkyScreen(bot)) \ No newline at end of file diff --git a/cogs/llama.py b/cogs/llama.py index 9e67212..2712181 100644 --- a/cogs/llama.py +++ b/cogs/llama.py @@ -159,17 +159,12 @@ class Llama(commands.Cog): channel_vars = await self.get_channel_config(message.channel.id) chat_history_string = await self.log_chat_and_get_history(message, logfile, channel_vars) # Chat Response - try: - if channel_vars["llama_enabled"] and not message.author.bot or self.bot_id in [x.id for x in message.mentions]: - if message.content and message.content[0] != "!": - await self.chat_response(message, channel_vars, chat_history_string) - elif not message.content: - await self.chat_response(message, channel_vars, chat_history_string) - except: - self.edit_channel_config(message.channel.id, "llama_enabled", False) + if channel_vars["llama_enabled"] and not message.author.bot or self.bot_id in [x.id for x in message.mentions]: + if message.content and message.content[0] != "!": + await self.chat_response(message, channel_vars, chat_history_string) + elif not message.content: + await self.chat_response(message, channel_vars, chat_history_string) async def setup(bot): - #await bot.add_cog(Llama(bot)) - #Temporarily disable this as it isn't really working properly - pass \ No newline at end of file + await bot.add_cog(Llama(bot)) \ No newline at end of file diff --git a/cogs/meshtastic.py b/cogs/meshtastic.py new file mode 100644 index 0000000..36f08e9 --- /dev/null +++ b/cogs/meshtastic.py @@ -0,0 +1,26 @@ +import logging +import discord +from discord.ext import commands +import meshtastic +import meshtastic.serial_interface + +class Meshtastic(commands.Cog): + + def __init__(self, bot): + self.bot = bot + self.logger = logging.getLogger("bot") + self.interface = meshtastic.serial_interface.SerialInterface() + + @commands.command( + description="Meshtastic", + help="Ask the magic ball a question.", + brief="Ask the magic ball a question.", + aliases=["mesh"] + ) + async def mesh(self, ctx, *args): + message = " ".join(args) + self.interface.sendText(message) + self.logger.info(f"Meshtastic command called by {ctx.author.name}") + +async def setup(bot): + await bot.add_cog(Meshtastic(bot)) \ No newline at end of file diff --git a/cogs/message_xp.py b/cogs/message_xp.py deleted file mode 100644 index a72c98b..0000000 --- a/cogs/message_xp.py +++ /dev/null @@ -1,169 +0,0 @@ -from discord.ext import commands -import discord -import json -import os -from cogs.base_cog.bot_base_cog import BotBaseCog - -class MessageXP(BotBaseCog): - - def __init__(self, bot): - super().__init__(bot) - self.setup(__class__.__name__) - - @commands.command() - async def stats(self, ctx): - author_id = str(ctx.author.id) - try: - xp_data = read_xp_file(self) - if author_id in xp_data: - level = get_level_from_xp(xp_data[author_id]) - await ctx.send(f"You are level {level} with {xp_data[author_id]} XP") - else: - await ctx.send("You have 0 XP") - except: - await ctx.send("Error getting XP") - - @commands.command() - async def show_json(self, ctx): - with open(os.path.join(self.data_dir, "xp.json"), "r") as xp_file: - xp_data = json.load(xp_file) - await ctx.send(xp_data) - - - @commands.Cog.listener() - async def on_message(self, message: discord.Message): - try: - author_id = str(message.author.id) - if message.author.bot: - return - else: - xp_data = read_xp_file(self) - if author_id in xp_data: - xp_data[author_id] += 1 - else: - xp_data[author_id] = 1 - - with open(os.path.join(self.data_dir, "xp.json"), "w") as xp_file: - json.dump(xp_data, xp_file) - except Exception as e: - self.logger.error(f"Error adding XP: {e}") - -def read_xp_file(self): - try: - with open(os.path.join(self.data_dir, "xp.json"), "r") as xp_file: - xp_data = json.load(xp_file) - return xp_data - except Exception as e: - self.logger.error(f"No XP file found. Returning empty json object: {e}") - return {} - -def get_level_from_xp(xp): - xp_dict = { - 1: 0, - 2: 83, - 3: 174, - 4: 276, - 5: 388, - 6: 512, - 7: 650, - 8: 801, - 9: 801, - 10: 1_154, - 11: 1_358, - 12: 1_584, - 13: 1_833, - 14: 2_107, - 15: 2_411, - 16: 2_746, - 17: 3_115, - 18: 3_523, - 19: 3_973, - 20: 4_470, - 21: 5_018, - 22: 5_624, - 23: 6_291, - 24: 7_028, - 25: 7_842, - 26: 8_740, - 27: 9_730, - 28: 10_824, - 29: 12_031, - 30: 13_363, - 31: 14_833, - 32: 16_456, - 33: 18_247, - 34: 20_224, - 35: 22_406, - 36: 24_815, - 37: 27_473, - 38: 30_408, - 39: 33_648, - 40: 37_224, - 41: 41_171, - 42: 45_529, - 43: 50_339, - 44: 55_649, - 45: 61_512, - 46: 67_983, - 47: 75_127, - 48: 83_014, - 49: 91_721, - 50: 101_333, - 51: 111_945, - 52: 123_660, - 53: 136_594, - 54: 150_872, - 55: 166_636, - 56: 184_040, - 57: 203_254, - 58: 224_466, - 59: 247_886, - 60: 273_742, - 61: 302_288, - 62: 333_804, - 63: 368_599, - 64: 407_015, - 65: 449_428, - 66: 496_254, - 67: 547_953, - 68: 605_032, - 69: 668_051, - 70: 737_627, - 71: 814_445, - 72: 899_257, - 73: 992_895, - 74: 1_096_278, - 75: 1_210_421, - 76: 1_336_443, - 77: 1_475_581, - 78: 1_629_200, - 79: 1_798_808, - 80: 1_986_068, - 81: 2_192_818, - 82: 2_421_087, - 83: 2_673_114, - 84: 2_951_373, - 85: 3_258_594, - 86: 3_597_792, - 87: 3_972_294, - 88: 4_385_776, - 89: 4_842_295, - 90: 5_346_332, - 91: 5_902_831, - 92: 6_517_253, - 93: 7_195_629, - 94: 7_944_614, - 95: 8_771_558, - 96: 9_684_577, - 97: 10_692_629, - 98: 11_805_606, - 99: 13_034_431 - } - for level, xp_threshold in xp_dict.items(): - if xp < xp_threshold: - return level - 1 - return 99 - - -async def setup(bot): - await bot.add_cog(MessageXP(bot)) \ No newline at end of file diff --git a/cogs/phixxycom.py b/cogs/phixxycom.py index 84c23d4..ad8788b 100644 --- a/cogs/phixxycom.py +++ b/cogs/phixxycom.py @@ -192,7 +192,7 @@ class PhixxyCom(commands.Cog): except: self.logger.exception("Something went wrong in upload_ftp_ai_images") - async def answer_question(self, topic, model="gpt-4o-mini"): + async def answer_question(self, topic, model="gpt-3.5-turbo"): headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {os.getenv("openai.api_key")}', @@ -265,7 +265,7 @@ class PhixxyCom(commands.Cog): topic = await self.answer_question(question) self.logger.info("Writing blogpost") title_prompt = 'generate an absurd essay title about ' + topic - title = await self.answer_question(title_prompt, model="gpt-4o-mini") + title = await self.answer_question(title_prompt, model="gpt-3.5-turbo") prompt = 'Write a satirical essay with a serious tone titled: "' + title + '". Do not label parts of the essay.' content = await self.answer_question(prompt, model="gpt-4o") if title in content[:len(title)]: diff --git a/cogs/rss_feeds.py b/cogs/rss_feeds.py deleted file mode 100644 index fd5fff6..0000000 --- a/cogs/rss_feeds.py +++ /dev/null @@ -1,35 +0,0 @@ -from discord.ext import commands, tasks -from cogs.base_cog.bot_base_cog import BotBaseCog -import feedparser -import asyncio - -class RSSCog(BotBaseCog): - - def __init__(self, bot): - super().__init__(bot) - self.setup(__class__.__name__) - self.rss_base_url = 'https://secure.runescape.com/m=adventurers-log/rssfeed?searchName=' - self.usernames = ['Deadifyed', 'Frozener', 'Tsuki no ko', 'blue boomer4'] - self.last_items = {key: None for key in self.usernames} - self.check_rss.start() - - @tasks.loop(minutes=5) - async def check_rss(self): - for name in self.usernames: - rss_url = self.rss_base_url + name.replace(' ','%20') - feed = feedparser.parse(rss_url) - latest_item = feed.entries[0] if feed.entries else None - - if latest_item and latest_item.title != self.last_items[name]: - self.last_items[name] = latest_item.title - channel = self.bot.get_channel(895388842834673696) - await channel.send(f"{name}: {latest_item.description}") - - await asyncio.sleep(60) - - @check_rss.before_loop - async def before_check_rss(self): - await self.bot.wait_until_ready() - -async def setup(bot): - await bot.add_cog(RSSCog(bot)) \ No newline at end of file diff --git a/cogs/ytdl.py b/cogs/ytdl.py deleted file mode 100644 index 09d2b06..0000000 --- a/cogs/ytdl.py +++ /dev/null @@ -1,93 +0,0 @@ -import os -import subprocess -import asyncio - -from discord.ext import commands, tasks -from cogs.base_cog.bot_base_cog import BotBaseCog - -class YoutubeDL(BotBaseCog): - - def __init__(self, bot): - super().__init__(bot) - self.setup(__class__.__name__) - self.check_for_downloads.start() - - ''' @commands.command() - async def youtubedl(self, ctx): - try: - # Expecting the command format to be !youtubedl - parts = ctx.message.content.split(" ") - if len(parts) < 3: - await ctx.send("Usage: !youtubedl ") - return - - url = parts[1] - video_or_audio = parts[2] - - # Run the subprocess - process = subprocess.Popen( - ["python3", "youtubedl.py", url, video_or_audio], - cwd="data/ytdl", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - - # Wait for the process to complete and read the output - stdout, stderr = process.communicate() - - # Send the output back to the user - #await ctx.send(f"std out: {stdout.decode('utf-8')}") if stdout else await ctx.send("No stdout output") - #await ctx.send(f"std err: {stderr.decode('utf-8')}") if stderr else await ctx.send("No stderr output") - await ctx.send(f"Downloading {video_or_audio} from {url}...", suppress_embeds=True) - - except Exception as e: - #await ctx.send(f"Error: {e}") - await ctx.send("Usage: !youtubedl ")''' - - @commands.command() - async def youtubedl(self, ctx): - try: - # Expecting the command format to be !youtubedl - parts = ctx.message.content.split(" ") - if len(parts) < 3: - await ctx.send("Usage: !youtubedl ") - return - - url = parts[1] - video_or_audio = parts[2] - - # Create a subprocess - process = await asyncio.create_subprocess_exec( - "python3", "youtubedl.py", url, video_or_audio, - cwd="data/ytdl", - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE - ) - - # Write a message that the download has started - await ctx.send(f"Downloading {video_or_audio} from {url}...") - - # Read stdout and stderr (non-blocking) - stdout, stderr = await process.communicate() - - # Send the output back to the user - if stdout: - await ctx.send(f"std out: {stdout.decode('utf-8')}") - if stderr: - await ctx.send(f"std err: {stderr.decode('utf-8')}") - - except Exception as e: - await ctx.send(f"Error: {e}") - - #create a task - @tasks.loop(seconds=10) - async def check_for_downloads(self): - for file in os.listdir("data/ytdl"): - if file.endswith(".txt"): - with open(f"data/ytdl/{file}", "r") as f: - url = f.read() - await self.bot.get_channel(544408659174883328).send(f"{url}") - os.remove(f"data/ytdl/{file}") - -async def setup(bot): - await bot.add_cog(YoutubeDL(bot)) \ No newline at end of file diff --git a/data/ytdl/youtubedl.py b/data/ytdl/youtubedl.py deleted file mode 100644 index 1814d03..0000000 --- a/data/ytdl/youtubedl.py +++ /dev/null @@ -1,54 +0,0 @@ -from sys import argv -import os -import time -import subprocess -#usage python3 youtubedl.py - -def download(url, video_or_audio): - if video_or_audio == "video": - process = subprocess.Popen(["yt-dlp", "--yes-playlist", f"{url}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - process.wait() - return True - elif video_or_audio == "audio": - process = subprocess.Popen(["yt-dlp", "-x", "--yes-playlist", url], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - process.wait() - return True - else: - print("Invalid argument") - return False - -def zip_all_files(): - #zip all files - current_epoch = time.time() - output_file = f"{current_epoch}.zip" - os.system(f"zip -r {output_file} *") - return output_file - -def upload_to_litterbox(input_file): - ''' If you want to make curl requests to the API, here is an example. Allowed values for "time" are 1h, 12h, 24h, and 72h. - curl -F "reqtype=fileupload" -F "time=1h" -F "fileToUpload=@cutie.png" https://litterbox.catbox.moe/resources/internals/api.php''' - command = f"curl -F 'reqtype=fileupload' -F 'time=1h' -F 'fileToUpload=@{input_file}' https://litterbox.catbox.moe/resources/internals/api.php" - output_url = os.popen(command).read() - #delete all files in current directory except this script - file_types = ["zip", "mp4", "mp3", "webm", "wav", "m4a", "flac", "ogg", "opus", "wma", "aac", "m4p", "m4b", "m4r", "m4v", "mp2", "mp3", "mp4", "mpa", "mpeg", "mpg", "mpv", "mxf", "ogg", "oga", "ogv", "ogx", "spx", "wav", "webm", "wma", "wv", "wvx", "weba", "webm", "webp", "wmv"] - for file in os.listdir(): - if file.split(".")[-1] in file_types: - os.remove(f"{file}") - pass - return output_url - -def main(): - url, video_or_audio = argv[1], argv[2] - print(url, video_or_audio) - if download(url, video_or_audio): - zip_file = zip_all_files() - output_url = upload_to_litterbox(zip_file) - print(output_url) - with open(f"{time.time()}.txt", "w") as output_file: - output_file.write(output_url) - output_file.close() - else: - print("Invalid argument") - -if __name__ == "__main__": - main() diff --git a/flask_templates/index.html b/flask_templates/index.html deleted file mode 100644 index 757eda7..0000000 --- a/flask_templates/index.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - Sparkytron Config - - - -
-

Warning!

-

This information is stored in PLAIN TEXT in a .env file!

-
- {% for key, value in key_value_pairs.items() %} -
- -
- -
-
- {% endfor %} - - - - {% with messages = get_flashed_messages() %} - {% if messages %} - {% for message in messages %} - - {% endfor %} - {% endif %} - {% endwith %} -
-
- - \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index afdebf7..173a812 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,4 @@ aiofiles inky wakeonlan beautifulsoup4 -Flask[async] -waitress -feedparser \ No newline at end of file +meshtastic \ No newline at end of file diff --git a/sparkytron_webui.py b/sparkytron_webui.py deleted file mode 100644 index bb75e1e..0000000 --- a/sparkytron_webui.py +++ /dev/null @@ -1,26 +0,0 @@ -import asyncio -import discord -import os -import subprocess -import sys -from dotenv import load_dotenv -from src.bot import bot -from src.webui import flask_app -from waitress import serve - -def get_flask_app(process): - flask_app.bot_process = process - flask_app.secret_key = "woaoaoahaowhawoiahoahhhhhh" - return flask_app - -def main(): - load_dotenv() - flask_port = os.getenv("flask_port") - if not flask_port: - flask_port = '5000' - process = subprocess.Popen([sys.executable, "sparkytron3000.py"]) - flask_app = get_flask_app(process) - serve(flask_app, host='0.0.0.0', port=flask_port) - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/src/bot.py b/src/bot.py index 52cb604..8c00b66 100644 --- a/src/bot.py +++ b/src/bot.py @@ -10,6 +10,7 @@ intents.message_content = True bot = commands.Bot(command_prefix='!', intents=intents) logger = src.logger.logger_setup() + async def load_cogs(bot: commands.Bot, cog_path: str) -> None: for cog_file in os.listdir(cog_path): if cog_file[-3:] == '.py': @@ -26,7 +27,6 @@ async def on_ready(): await utils.delete_all_files("tmp/") await load_cogs(bot, 'cogs/') logger.info('We have logged in as {0.user}'.format(bot)) - print("If using the webui, visit http://localhost:5000 to change config!") except: logger.warning(f"Error in on_ready") @@ -43,4 +43,4 @@ async def on_message(ctx): except discord.ext.commands.errors.CommandNotFound: logger.info("Command not found.") except Exception as e: - logger.warning(f"Error processing commands: {e}") \ No newline at end of file + logger.warning(f"Error processing commands: {e}") diff --git a/src/webui.py b/src/webui.py deleted file mode 100644 index 5b4306c..0000000 --- a/src/webui.py +++ /dev/null @@ -1,46 +0,0 @@ -import logging -import os -import subprocess -import sys - -from flask import Flask, render_template, request, flash - -logger = logging.getLogger("bot") -flask_app = Flask(__name__, template_folder='../flask_templates') - -def read_env(filename): - if os.path.exists(filename): - with open(filename, 'r') as file: - key_value_pairs = {} - for line in file: - try: - key, value = line.strip().split('=') - key = key.strip() - value = value.strip()[1:-1] - key_value_pairs[key] = value - except: - print("This line isnt a kv pair") - return key_value_pairs - else: - return None - -@flask_app.route('/', methods=['GET', 'POST']) -async def index(): - key_value_pairs = read_env('.env') - if not key_value_pairs: - logger.warn("No .env file found! Copying defaults.") - key_value_pairs = read_env('.env_default') - form_dict = {} - if request.method == 'POST': - if key_value_pairs: - for form_name in key_value_pairs.keys(): - form_dict[form_name] = request.form[form_name] - with open('.env', 'w') as file: - for key, value in form_dict.items(): - file.write(f"{key}='{value}'\n") - flask_app.bot_process.terminate() - flask_app.bot_process = subprocess.Popen([sys.executable, "sparkytron3000.py"]) - message = "Variables Updated!" - flash(message) - return render_template('index.html', key_value_pairs = key_value_pairs) -