def main(): logger = get_globals("logger") url = get_globals("auth|database login url") logger.indicate_process_start("Connecting to Database ...") try: cl = pymongo.MongoClient(url) # To test, if it can actually fetch data _ = cl["executer_database"]["servers"].find()[0] except (pymongo.errors.ConfigurationError, pymongo.errors.OperationFailure): logger.indicate_process_outcome( "\nAn error occurred while trying to setup the database client." " See stderr for more information") logger.log_traceback() set_globals(database_access=False) else: set_globals(database_client=cl) logger.indicate_process_outcome("Success") set_globals(database_access=True) start = datetime.datetime.now() try: run() except Exception as e: time_display_format = get_globals("general|time display template") logger.log_line("-----------------") logger.log_line( f"An error of type {type(e)} occurred at" f" {datetime.datetime.now().strftime(time_display_format)}") logger.log_line( f"Bot run for {(datetime.datetime.now() - start).seconds}s. See stderr for more information" ) logger.log_traceback() logger.log_line("=" * 100) return 1 return -1
def cah_host(inp): global current_cah_game current_cah_game = Game(rando=("rando" in inp.args)) if "full" in inp.args: meta_data = current_cah_game.add_libs(get_globals("cah config|full")) else: meta_data = current_cah_game.add_libs(inp.args[1:]) if len(current_cah_game._whites_tot) < 1: current_cah_game = None return Out("No white cards", inp.channel) if len(current_cah_game._blacks_tot) < 1: current_cah_game = None return Out("No black cards", inp.channel) current_cah_game.join(inp.author) em = discord.Embed(title="New c-a-h game", colour=0x000000) em.description = inp.author.display_name + "just created a new \"Cards against Humanity\" game\n\n__Libraries:__" for meta_instance in meta_data: em.add_field(name=meta_instance["filename"], value=meta_instance["outcome"]) if meta_instance["outcome"] != "success": message = Out( meta_instance["outcome"] + ":\n" + "\n".join([str(x) for x in meta_instance["errors"]]) + "\nin file " + meta_instance["filename"], inp.channel) push_message(message) em.set_author(name="CaH", icon_url=get_globals("cah config|image url")) return Out(em, inp.channel)
def update_database_server(): if get_globals("database_access"): server_collection = get_globals( "database_client|executer_database|servers") server_set = set(map(lambda x: x.id, client.guilds)) database_set = set( map(lambda x: x["discord_id"], server_collection.find())) db_create = server_set - database_set db_delete = database_set - server_set for create_database in db_create: logger.log_line(f"\"{create_database}\" server needs database") server_obj = client.get_guild(create_database) database_object = { "discord_id": server_obj.id, "name": server_obj.name, "functions": [], #"cah_librairies": get_globals("cah functions|full"), "cah_librairies": {}, "youtube_follow_channels": [], "response_functions": {}, # "default_channel_id": server_obj.fetch_channels()[0].id "default_channel_id": 0 } server_collection.insert_one(database_object) for delete_database in db_delete: logger.log_line(f"[delete \"{delete_database}\" database]") else: logger.log_line( "Server Collection cannot be updated. Client has no connection to database" )
async def on_message(message): if message.author == client.user: return if isinstance( message.channel, (discord.DMChannel, discord.GroupChannel)) or not get_globals("database_access"): server_data = get_globals("default server data") server_data["default_channel_id"] = message.id else: server_data = get_globals( "database_client|executer_database|servers").find( {"discord_id": message.guild.id})[0] input_ = ResponseInput( message, { **get_globals("safe_data"), "server data": server_data }) input_.check() func = special_reaction(input_) if func is None and input_.command: if input_.request_delete and message.channel.permissions_for( message.author).manage_messages: await message.delete() func = get_response_function(input_.args[0]) if func is not None: if asyncio.iscoroutinefunction(func): try: await func(input_) except Exception: push_message( ResponseOutput( f"A python error occurred insight of the response function: \n" f"```{format_exc(limit=10)}```", input_.channel)) else: output = 0 try: output = func(input_) except Exception: push_message( ResponseOutput( f"A python error occurred insight of the response function: \n" f"```{format_exc(limit=10)}```", input_.channel)) if isinstance(output, ResponseOutput): push_message(output) await empty_queue()
def initiate_routines(loop): if get_globals("database_access"): server_collection, routine_list = get_globals( "database_client|executer_database|servers", "routine_list") for x in server_collection.find(): function_list = x["functions"] for item in function_list: if item in routine_list: func, time = routine_list[item] loop.create_task(routine_def(func, x, time)) logger.log_line( f"\t\"{func.__name__}\" routine initiated ({time}s) for {x['name']}" ) set_globals(routine_list=routine_list)
def help_(inp): em = discord.Embed(title="Bot Help", color=0xFCDE53) for name, i in get_globals("response_dict").items(): show_state = i["maintenance state"] != FunctionMaintenanceState.FUNCTIONAL description = i["description"] + (": " + i["maintenance state"].__str__() if show_state else "") em.add_field(name="%" + name, value=description, inline=True) return Out(em, inp.channel)
def yt_check(data): client = get_globals("client") for channel, prev_video in data["youtube_follow_channels"].items(): # Get newest video url = f"https://www.googleapis.com/youtube/v3/search?part=snippet&channelId={channel}&maxResults=1&" \ "order=date&key=AIzaSyAHpipWEHy1I3YIkdjyPdCsrSzE3hcKXhE" rep = requests.get(url) print("request yt api", datetime.now().isoformat()) content_object = json.loads(rep.text) if "error" in content_object: stderr.write(f"Error {content_object['error']['code']} occurred in 'yt_check' routine:\n" f"{content_object['error']['message']}") return video = content_object["items"][0] video_id = video["id"]["videoId"] if video_id != prev_video: # Found a new video # Display message em = discord.Embed(title=f"{video['snippet']['channelTitle']} uploaded a new video", colour=YOUTUBE_RED)\ .add_field(name=video["snippet"]["title"], value=video["snippet"]["description"], inline=False)\ .set_author(name="Executer Youtube Division", icon_url=YOUTUBE_IMAGE_URL) # Update the database current_list = data["youtube_follow_channels"] current_list[channel] = video_id update_server_data(data["discord_id"], youtube_follow_channels=current_list) main_channel = client.get_channel(data["default_channel_id"]) push_message(Out(em, main_channel)) push_message(Out("https://www.youtube.com/watch?v=" + video_id, main_channel))
def random_sentence(inp): category = "lefty_problem" if len(inp.args) > 1: category = inp.args[1] matrix = get_globals("function specific|random_sentence_matrix").get(category, [[""]]) sentence = " ".join([random.choice(i) for i in matrix]) return Out(sentence, inp.channel)
def approves(inp): client = get_globals("client") em = discord.Embed(title="Executor approval Rating", color=0x51ff00, description=f"{client.user.name} approves :white_check_mark:") em.set_author(name=client.user.name, icon_url=client.user.avatar_url) em.set_footer(text="determined after long consideration") return Out(em, inp.channel)
def run(): """ entrance point; gets bot to run """ logger.indicate_process_start("Connecting ..." + " " * 85) global client if client.loop.is_closed(): client = restore_client() try: client.run(get_globals("auth|token")) except Exception: print("Nope")
async def on_ready(): time_display_template = get_globals("general|time display template") logger.indicate_process_outcome( f"Ready\n{datetime.datetime.now().strftime(time_display_template)}") update_database_server() logger.log_line("Initiate routines ...") initiate_routines(client.loop) logger.log_block( "", "All is nominal", "", " +---------------------------------------+", " | E X E C U T E R B O T S T A R T |", " +---------------------------------------+", "", "===================================================================================================" )
import discord import re from backend import ResponseOutput as Out, FunctionMaintenanceState from program_base import get_globals, set_globals, push_message, register_response_function as register from cah_core import * current_cah_game = None CAH_IMAGE_URL, BLACK, WHITE = get_globals("cah config|image url", "cah config|black", "cah config|white") """ def cards_against_humanity(inp): global current_cah_game cah_data = get_globals("cah config") args = inp.args[1:] author_ment = inp.author.mention #if re.match(r"^%?cah (play \d{1,3}|choose \d|host (rando)?|join|close host|finish|stats|random)\s*$", inp.text_content) is None: # pass if args[0] not in ("host", "random") and current_cah_game is None: return Out("No game initialized", inp.channel) if len(args) >= 2: command = args[0] if command == "play": if any([re.match(r"^\w*\d$", x) is None for x in args[1:]]): return Out("All arguments must be positive integers between 0 and 9", inp.channel) if current_cah_game.game_stat != 1: return Out("You cannot play now", inp.channel)
def rando(cls, game, id): bot_client = get_globals("client") return Player(bot_client.user, game, id, True)
async def on_disconnect(): time_display_template = get_globals("general|time display template") logger.log_line( f"Client disconnected at {datetime.datetime.now().strftime(time_display_template)}\n###\n" )
import asyncio import datetime import discord from program_base import get_globals, restore_client, set_globals, pop_message, push_message, get_response_function, special_reaction,\ can_pop from traceback import format_exc from backend import ResponseInput, ResponseOutput client, logger = get_globals("client", "logger") def update_database_server(): if get_globals("database_access"): server_collection = get_globals( "database_client|executer_database|servers") server_set = set(map(lambda x: x.id, client.guilds)) database_set = set( map(lambda x: x["discord_id"], server_collection.find())) db_create = server_set - database_set db_delete = database_set - server_set for create_database in db_create: logger.log_line(f"\"{create_database}\" server needs database") server_obj = client.get_guild(create_database) database_object = { "discord_id": server_obj.id, "name": server_obj.name, "functions": [], #"cah_librairies": get_globals("cah functions|full"), "cah_librairies": {},