async def send_keyboard_input(self, string, press_enter_after_string=False): try: string = string.upper() logger.debug(string) # Special keys if string in ["UP", "DOWN", "LEFT", "RIGHT"]: key = getattr(uinput, "KEY_" + string) self.device.emit(key, 1) await asyncio.sleep(0.4) self.device.emit(key, 0) await asyncio.sleep(0.4) else: for i in string: logger.debug("Clicking {}".format(i)) key = getattr(uinput, "KEY_" + i) self.device.emit(key, 1) await asyncio.sleep(0.4) self.device.emit(key, 0) await asyncio.sleep(0.4) if press_enter_after_string: self.device.emit(uinput.KEY_ENTER, 1) await asyncio.sleep(0.4) self.device.emit(uinput.KEY_ENTER, 0) await asyncio.sleep(0.4) except Exception as e: logger.exception(e)
async def generate_quiz_question(self): category = "" question = "" options = "" correct_answer = "" try: session = aiohttp.ClientSession() url = 'https://opentdb.com/api.php?amount=1&category=9&difficulty={}&type=multiple'.format( self.QUIZ_DIFFICULTY) async with session.get(url) as resp: data = await resp.read() json_response = json.loads(data) await session.close() category = json_response['results'][0]['category'] question = json_response['results'][0]['question'] correct_answer = json_response['results'][0]['correct_answer'] incorrect_answers = json_response['results'][0][ 'incorrect_answers'] logger.debug("Category: {}".format(category)) logger.debug("Question: {}".format(question)) logger.debug("Answer: {}".format(correct_answer)) options = incorrect_answers.copy() options.append(correct_answer) random.shuffle(options) except Exception as e: logger.exception(e) return category, question, options, correct_answer
async def _play(self, ctx: commands.Context, *, search: str): """Plays a song. If there are songs in the queue, this will be queued until the other songs finished playing. This command automatically searches from various sites if no URL is provided. A list of these sites can be found here: https://rg3.github.io/youtube-dl/supportedsites.html """ if not ctx.voice_state.voice: await ctx.invoke(self._join) async with ctx.typing(): try: source = await YTDLSource.create_source(ctx, search, loop=self.bot.loop) except YTDLError as e: # await ctx.send('An error occurred while processing this request: {}'.format(str(e))) logger.exception(e) await ctx.send('Oops. Can\'t sing now. Try later bro.') else: song = Song(source) await ctx.voice_state.songs.put(song) await ctx.send('Enqueued {}'.format(str(source)))
async def get_fact(message_channel): logger.debug("advice") wait_message = await message_channel.send("One interesting fact coming right up...") try: session = aiohttp.ClientSession() async with session.get("https://useless-facts.sameerkumar.website/api") as resp: data = await resp.read() json_response = json.loads(data) await session.close() await wait_message.edit(content='*\"{}\"*'.format(json_response['data'])) except Exception as e: logger.exception(e) await message_channel.send('Sorry can\'t think of anything')
async def get_advice(message_channel): logger.debug("advice") wait_message = await message_channel.send("Let me think...") try: session = aiohttp.ClientSession() async with session.get("https://api.adviceslip.com/advice") as resp: data = await resp.read() json_response = json.loads(data) await session.close() await wait_message.edit(content='*\"{}\"*'.format(json_response['slip']['advice'])) except Exception as e: logger.exception(e) await message_channel.send('Sorry can\'t think of anything')
async def runcmd(self, ctx, *args): logger.debug(args) if ctx.message.author.id == int(ADMIN_ID): try: result = subprocess.Popen(args, stdout=subprocess.PIPE) logger.debug(result.stdout) out = "" for line in result.stdout: out += line.decode('utf-8') logger.debug(out) await ctx.send("```{}```".format(out)) except Exception as e: logger.exception(e) else: await ctx.send('```Only my master can use this command.```')
async def _sysinfo(self, ctx): try: if ctx.author.id == int(ADMIN_ID): # wait_message = await ctx.send("Processing... Please wait. This might take sometime") # async with ctx.typing(): embed = discord.Embed( title="System Info", description="Showing my host hardware/software information", colour=discord.Color.gold()) embed.set_footer(text="Hope that was helpful, bye!") embed.set_author(name="Bro Bot", icon_url=self.bot.user.avatar_url) embed.set_thumbnail(url=ctx.guild.icon_url) result = subprocess.Popen(['neofetch', '--stdout'], stdout=subprocess.PIPE) for line in result.stdout: line = line.decode('utf-8').strip('\n').split(':') if len(line) == 2: if line[0] == "OS" or line[0] == "Host": embed.add_field(name=line[0], value=line[1], inline=False) else: embed.add_field(name=line[0], value=line[1], inline=True) # Raspberry Pi Only!!! if os.uname()[1] == "raspberrypi": temp = subprocess.Popen( ['/opt/vc/bin/vcgencmd', 'measure_temp'], stdout=subprocess.PIPE) for line in temp.stdout: line = line.decode('utf-8').strip('\n').split('=') if len(line) == 2: embed.add_field(name="CPU Temp", value=line[1], inline=True) url = await get_public_url() embed.add_field(name="Public URL", value=url, inline=False) # await wait_message.edit(content='', embed=embed) await embed_send(ctx, embed) else: await ctx.send('```Only my master can use this command.```') except Exception as e: logger.exception(e)
async def get_news(message_channel): logger.debug("news") # wait_message = await message_channel.send("Bringing you the latest BREAKING NEWS!") try: session = aiohttp.ClientSession() # read Bot Token from token file in keys folder with open('keys/news_api') as f: news_api_key = f.read() news_url = "https://newsapi.org/v2/top-headlines?sources=bbc-news&language=en&apiKey={}".format(news_api_key) async with session.get(news_url) as resp: data = await resp.read() json_response = json.loads(data) await session.close() embed_list = [] embed = "" news_message = "" for index in range(7): embed = discord.Embed(title=json_response['articles'][index]['title'], description=json_response['articles'][index]['description'], url=json_response['articles'][index]['url'], colour=discord.Color.darker_grey()) embed.set_thumbnail(url=json_response['articles'][index]['urlToImage']) embed_list.append(embed) news_message += "{}. {}\n".format(index + 1, json_response['articles'][index]['title']) # await wait_message.edit(content="```TOP HEADLINES:\n```".format(news_message)) if isinstance(message_channel, discord.ext.commands.context.Context) or isinstance(message_channel, discord.channel.TextChannel): # await message_channel.send(content="```TOP HEADLINES:\n{}```".format(news_message)) async with aiohttp.ClientSession() as session: webhook = Webhook.from_url( BRO_NEWS_WEBHOOK_URL, adapter=AsyncWebhookAdapter(session)) await webhook.send(content="```TOP HEADLINES```", embeds=embed_list) elif isinstance(message_channel, discord_slash.context.SlashContext): await message_channel.send(content="```TOP HEADLINES```", embeds=embed_list) else: logger.error("invalid ctx type: {}".format(type(message_channel))) await message_channel.send("ZZZzzzz") except Exception as e: logger.exception(e) await message_channel.send("No news for you.")
async def send_keyboard_shortcut(self, list_of_keys): try: logger.debug(list_of_keys) for i in list_of_keys: logger.debug("Holding {}".format(i)) key = getattr(uinput, "KEY_" + i.upper()) self.device.emit(key, 1) await asyncio.sleep(0.4) for i in list_of_keys: logger.debug("Releasing {}".format(i)) key = getattr(uinput, "KEY_" + i) self.device.emit(key, 0) await asyncio.sleep(0.4) except Exception as e: logger.exception(e)
async def on_message(self, message): # logger.debug(message.content) if message.author == self.bot.user: return try: if not self.game_mode: # to process messages only if game has started return user_input = message.content.split(',') # validations if len(user_input) > 2: return if int(user_input[0]) < 0 or int(user_input[0]) > 2 or int(user_input[1]) < 0 or int(user_input[1]) > 2: return if self.bot_thinking: await message.channel.send("Slow down Bro. Try again...") return game = games[message.guild.id] # adding check to see if position is already filled if game.board[int(user_input[0])][int(user_input[1])] == ".": self.bot_thinking = True # added flag to handle user input spam while bot is executing api game.board[int(user_input[0])][int(user_input[1])] = game.player await message.channel.send(game.beautify_board()) if game.hasWon(game.board): await message.channel.send("Congratulations! Player has won :trophy: :first_place:") del games[message.guild.id] # delete game instance self.bot_thinking = False logger.debug(games) return elif game.hasWon(game.board) is None: await message.channel.send("Match drawn :handshake:") del games[message.guild.id] # delete game instance self.bot_thinking = False logger.debug(games) return await message.channel.send("Thinking...") # await asyncio.sleep(0.25) logger.debug("DIFFICULTY:") logger.debug(game.difficulty) post_data = { "positions": game.board, "player": "X", "difficulty": game.difficulty } async with aiohttp.ClientSession() as session: async with session.post(url, json=post_data) as resp: user_input = await resp.json() if user_input["move"]: game.board[int(user_input["move"][0])][int(user_input["move"][1])] = game.computer await message.channel.send(game.beautify_board()) self.bot_thinking = False if game.hasWon(game.board): await message.channel.send("GrandMaster Bro wins! :robot:") del games[message.guild.id] # delete game instance logger.debug(games) elif game.hasWon(game.board) is None: await message.channel.send("Match drawn :handshake:") del games[message.guild.id] # delete game instance logger.debug(games) else: await message.channel.send("Position already filled. Try some other coordinate...") except ValueError as vale: logger.exception(vale) except Exception as e: logger.exception(e) self.bot_thinking = False
async def _stats(self, ctx, user: discord.Member): try: wait_message = await ctx.send( "Processing... Please wait. This might take sometime") embed = "" if not user: try: logger.debug("no user given...") embed = discord.Embed( title="Stats", description="Showing random stats for this server", colour=discord.Color.blue()) embed.set_footer(text="Hope that was helpful, bye!") embed.set_author(name="Bro Bot", icon_url=self.bot.user.avatar_url) embed.set_thumbnail(url=ctx.guild.icon_url) server = ctx.message.author.guild server_name = server.name server_owner = server.owner.mention server_create_date = server.created_at.__format__( '%d/%B/%Y') server_member_count = server.member_count logger.debug("*****************************") logger.debug( "Server name: {}\nserver owner: {}\nserver created at: {}\nTotal number of members: {}" .format(server_name, server_owner, server_create_date, server_member_count)) embed.add_field(name="Server Name", value=server_name, inline=False) embed.add_field(name="Server Owner", value=server_owner, inline=True) embed.add_field(name="Server Create Date", value=server_create_date, inline=True) embed.add_field(name="Total Members", value=server_member_count, inline=True) # channel = bot.get_channel(GENERAL_CHANNEL_ID) # messages = await channel.history(limit=None).flatten() messages = await ctx.channel.history(limit=None).flatten() logger.debug("Total messages: {}".format(len(messages))) embed.add_field(name="Total messages in this channel", value=str(len(messages)), inline=False) authors_count = Counter() word_count = Counter() message_list = list() bro_in_message_count = 0 # pre processing full_stopwords = stopwords.words('english') full_stopwords.extend(ADDITIONAL_STOPWORDS) for message in messages: if "bro" in str(message.content).lower(): bro_in_message_count += 1 authors_count.update({message.author.name: 1}) word_list = message.content.split() filtered_words = [ word for word in word_list if word not in full_stopwords ] message_list += filtered_words word_count.update(message_list) authors_count.pop('notDiegoDelavega', None) # removing test users from stat top = authors_count.most_common(1) logger.debug( "Most talkative bro: {} talked {} times".format( top[0][0], top[0][1])) value = str(top[0][0] if ctx.guild.get_member_named( top[0][0]) is None else ctx.guild.get_member_named( top[0][0]).mention) + " (" + str( top[0][1]) + " messages)" logger.debug(value) embed.add_field(name="Most Talkative Bro", value=value, inline=False) low = min(authors_count, key=authors_count.get) logger.debug( "Least talkative bro: {} talked {} time(s)".format( low, authors_count[low])) value = str( low if ctx.guild.get_member_named(low) is None else ctx .guild.get_member_named(low).mention) + " (" + str( authors_count[low]) + " messages)" embed.add_field(name="Least Talkative Bro", value=value, inline=True) top_authors = "" if len(authors_count) >= 5: logger.debug("Top 5 talkative Bros") for author, message_count in authors_count.most_common( 5): logger.debug("{}: {} times".format( author, message_count)) top_authors += str( author if ctx.guild.get_member_named(author) is None else ctx.guild.get_member_named(author).mention ) + " (" + str(message_count) + " messages) \n" embed.add_field(name="Top 5 Talkative Bros", value=top_authors, inline=False) top_string = "" if len(word_count) >= 5: logger.debug("Top five words used here are:") for word, count in word_count.most_common(5): logger.debug("{}: {} times".format(word, count)) top_string += str(word) + " (" + str( count) + " times) \n" embed.add_field(name="Top 5 words used here", value=top_string, inline=False) logger.debug("Bro was mentioned {} times!".format( bro_in_message_count)) embed.add_field(name="Bro Count", value=str(bro_in_message_count), inline=False) logger.debug("*****************************") except Exception as e: logger.exception(e) else: embed = discord.Embed( title="Stats", description="Showing random stats for user", colour=discord.Color.purple()) embed.set_footer(text="Hope that was helpful, bye!") embed.set_author(name="Bro Bot", icon_url=self.bot.user.avatar_url) embed.set_thumbnail(url=user.avatar_url) logger.debug("*****************************") logger.debug("user name: {}".format(user.mention)) logger.debug("user join date: {}".format( user.joined_at.__format__('%d/%B/%Y @%H:%M:%S'))) embed.add_field(name="User Name", value=user.mention, inline=False) embed.add_field(name="User Join Date", value=user.joined_at.__format__('%d/%B/%Y'), inline=False) messages = await ctx.channel.history(limit=None).flatten() message_list = list() word_count = Counter() for message in messages: if user == message.author: message_list += str(message.content).split() word_count.update(message_list) top_string = "" if len(word_count) >= 5: logger.debug("Top five words used by {}:".format( user.display_name)) top_name = "Top 5 words used by {} in this server:".format( user.display_name) for word, count in word_count.most_common(5): logger.debug("{}: {} times".format(word, count)) top_string += str(word) + " (" + str( count) + " times) \n" embed.add_field(name=top_name, value=top_string, inline=False) logger.debug("*****************************") await wait_message.delete() await embed_send(ctx, embed) # await wait_message.edit(content='', embed=embed) # await ctx.send(embed=embed) except Exception as e: logger.exception(e)
async def _quiz(self, ctx, arg=None): if not arg or arg == "noinstructions": self.QUIZ_MODE = True if arg != "noinstructions": await ctx.send( '```Instructions:\n' 'a. There will be a total of {} questions\n' 'b. Each question will have 4 options with 100 pts for correct answer\n' 'c. To answer, participants have to click on the appropriate reaction\n' 'd. Participants have {} seconds to answer each question\n' 'e. Selecting more than one choice will result in DISQUALIFICATION\n' 'f. Participant with the most points is the WINNER!\n```'. format(self.QUIZ_MAX_QUESTIONS, self.QUIZ_QUESTION_WAIT_TIME)) await asyncio.sleep(2) await ctx.send('```Game begins in 25 seconds...```') await asyncio.sleep(25) question_number = 1 participant_score = { } # dictionary which stores participant name and score while question_number <= self.QUIZ_MAX_QUESTIONS: if not self.QUIZ_MODE: # Stop quiz mode return async with ctx.typing(): category, question, options, answer = await self.generate_quiz_question( ) message = await ctx.send( html.unescape('\n**Question {}**\n' '**{}**\n' ':one: {}\n' ':two: {}\n' ':three: {}\n' ':four: {}\n'.format( question_number, question, options[0], options[1], options[2], options[3]))) emojis = [ "{}\N{COMBINING ENCLOSING KEYCAP}".format(num) for num in range(1, 5) ] # emoji code for 1,2,3,4 for emoji in emojis: await message.add_reaction(emoji) await asyncio.sleep(.75) participant_response = {} # dictionary to record user response # Give participants some time to react before moving on to next question time_at_start = datetime.datetime.today().timestamp() target_time = time_at_start + self.QUIZ_QUESTION_WAIT_TIME # wait for QUIZ_QUESTION_WAIT_TIME seconds for response logger.debug("time_at_start {}".format(time_at_start)) logger.debug("target_time {}".format(target_time)) while datetime.datetime.today().timestamp() < target_time: logger.debug("while now {}".format( datetime.datetime.today().timestamp())) try: reaction, user = await self.bot.wait_for( 'reaction_add', timeout=5, check=lambda reaction1, user1: str(reaction1.emoji ) in emojis) logger.debug("{} reacted with {}".format( user.display_name, reaction)) # TODO: remove older reaction if user changes option # message.remove_reaction(participant_response[user], user) participant_response.update( {user.display_name: emojis.index(reaction.emoji)}) except asyncio.TimeoutError: logger.debug("Timeout in Quiz") except Exception as e: logger.exception(e) await ctx.send("Correct answer was **{}**".format( html.unescape(answer))) for participant in participant_response: if participant == "Bro": continue if participant not in participant_score: participant_score.update({participant: 0}) if participant_response[participant] == options.index( answer): logger.debug( "Updating score for {}".format(participant)) participant_score.update({ participant: participant_score[participant] + 100 }) # show round score round_score = "" for participant in participant_score: round_score += "{}: {}\n".format( participant, participant_score[participant]) await ctx.send("```Score after Round {}\n{}```".format( question_number, round_score)) question_number += 1 await asyncio.sleep(3) logger.debug("quiz complete") winner = max(participant_score, key=participant_score.get) if participant_score[winner] != 0: await ctx.send( "{} is the WINNER. Congrats! :trophy: :first_place:". format(winner)) else: await ctx.send("No one scored any points. LOSERS!") elif arg.lower() == "stop": self.QUIZ_MODE = False await ctx.send('```Quiz mode stopped```') elif arg.lower() == "easy": self.QUIZ_DIFFICULTY = "easy" await ctx.send('```Quiz difficulty set to easy```') elif arg.lower() == "medium": self.QUIZ_DIFFICULTY = "medium" await ctx.send('```Quiz difficulty set to medium```') elif arg.lower() == "hard": self.QUIZ_DIFFICULTY = "hard" await ctx.send('```Quiz difficulty set to hard```') elif arg.isdigit(): if int(arg) > 30: await ctx.send( '```Quiz: max number of questions cannot be greater than 30```' ) else: self.QUIZ_MAX_QUESTIONS = int(arg) await ctx.send( '```Quiz: max number of questions set to {}```'.format( self.QUIZ_MAX_QUESTIONS)) else: # TODO: add option to change quiz config settings # number of questions # mode : easy, medium, hard # delay: ? pass
async def handler(request): logger.debug(request) # res = request.get_json() try: res = await request.json() logger.info(res) if 'title' in res.keys(): if "austria" in res['title'].lower(): gp_place = "Austria" elif "styria" in res['title'].lower(): gp_place = "Styria" elif "hungar" in res['title'].lower(): gp_place = "Hungar" elif "brit" in res['title'].lower(): gp_place = "Great%20Britain" elif "anniversary" in res['title'].lower(): gp_place = "70th%20Anniversary" elif "spanish" in res['title'].lower( ) or "spain" in res['title'].lower(): gp_place = "Spain" elif "belg" in res['title'].lower(): gp_place = "Belgium" elif "ital" in res['title'].lower(): gp_place = "Italy" elif "toscan" in res['title'].lower(): gp_place = "Tuscany" elif "romagna" in res['title'].lower(): gp_place = "Emilia%20Romagna" elif "turk" in res['title'].lower(): gp_place = "Turkey" elif "bahrain" in res['title'].lower(): gp_place = "Bahrain" elif "sakhir" in res['title'].lower(): gp_place = "Sakhir" elif "abu" in res['title'].lower(): gp_place = "Abu%20Dhab" else: gp_place = "" embed = discord.Embed(title=res['title'], description="Event in 15 minutes", colour=discord.Color.red()) embed.set_author(name="Bro Bot", icon_url=self.bot.user.avatar_url) if 'title' in res.keys(): embed.set_image( url= "https://www.formula1.com/content/dam/fom-website/2018-redesign-assets/Track%20icons%204x3/{}%20carbon.png.transform/8col/image.png" .format(gp_place)) embed.set_thumbnail( url= "https://www.google.com/url?sa=i&url=http%3A%2F%2Ft0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcTxRmfGmozn5szS7lnaBIceJ9sweiO45WBJmnsRzTdcjFAlLFQ4&psig=AOvVaw0Mp-oe1kLL3yOoi6vPptQV&ust=1594016113076000&source=images&cd=vfe&ved=0CA0QjhxqFwoTCKCj1_O6teoCFQAAAAAdAAAAABAD" ) if 'starts' in res.keys(): embed.add_field(name="Date", value=res['starts'] + " IST", inline=False) if 'location' in res.keys(): embed.add_field(name="Track", value=res['location'], inline=True) embed.set_footer(text="Hope that was helpful, bye!") for channel in self.channel_list: message_channel = self.bot.get_channel(channel) await message_channel.send(embed=embed) except Exception as e: logger.exception(e) return web.Response(text="Success")
async def _power(self, ctx, arg: str): logger.debug("PRE: {}".format(ctx)) try: if not arg: if isinstance(ctx, discord.ext.commands.context.Context): await ctx.send('```Usage:(ADMIN ONLY)\n' '{}power on : to switch on PC\n' '{}power off : to shutdown PC\n```'.format( COMMAND_PREFIX, COMMAND_PREFIX)) elif arg.lower() == "on": if ctx.author.id == int(ADMIN_ID): ''' api way ''' ''' session = aiohttp.ClientSession() data = {"action": "on"} api_path = os.path.join(ROOT_DIR, "keys/api") try: # read API endpoint from file # with open(api_path) as f: # pc_api = f.read().strip() # res = await session.post(pc_api, data=json.dumps(data), headers={'content-type': 'application/json'}) # await session.close() await ctx.send('```Done```') except Exception as e: logger.exception(e) ''' ''' direct call ''' master_mac_path = os.path.join(ROOT_DIR, "keys/master_mac") with open(master_mac_path) as f: master_mac = f.read().strip() logger.debug("Powering on PC") os.system("wakeonlan {}".format(master_mac)) await ctx.send("```Powering on PC```") else: await ctx.send("```Only my master can use this command```") elif arg.lower() == "off": admin_id_path = os.path.join(ROOT_DIR, "keys/admin_id") with open(admin_id_path) as f: admin_id = f.read().strip() if ctx.author.id == int(admin_id): master_ip_path = os.path.join(ROOT_DIR, "keys/master_ip") with open(master_ip_path) as f: master_ip = f.read().strip() logger.debug("Shutting down PC") os.system("ssh preetham@{} shutdown /s".format(master_ip)) await ctx.send('```Shutting down PC```') else: await ctx.send('```Only my master can use this command.```' ) else: await ctx.send('```Invalid entry```') if isinstance(ctx, discord.ext.commands.context.Context): await ctx.send('```Usage:(ADMIN ONLY)\n' '{}power on : to switch on PC\n' '{}power off : to shutdown PC\n```'.format( COMMAND_PREFIX, COMMAND_PREFIX)) except Exception as e: logger.exception(e) await ctx.send('```Zzzzz```')