async def update(): try: await self.client.change_presence( activity=discord.Game(name='{:,} Cases'.format( int(self.covidData.results['Global'] ['TotalConfirmed'])))) except: log("Failed to update bot status")
async def update(): try: await self.client.change_presence( activity=discord.Activity( name="c;help", type=discord.ActivityType.listening)) except: log("Failed to update bot status")
async def update(): try: await self.client.change_presence( activity=discord.Activity( name="{} servers".format( len(self.client.guilds)), type=discord.ActivityType.watching)) except: log("Failed to update bot status")
async def remove_rolemenu(): ''' Removes a message by its mid (message id). ''' if id == "0" or channel == "0": bot.log("Found no existing rolemenu") return message = channel.fetch_message(id) message.delete()
def run(self): log("Update Data daemon started.") while True: self.unstable_req = requests.get( 'https://api.covid19api.com/summary') if 199 < self.unstable_req.status_code < 300: self.req = self.unstable_req self.results = self.req.json() else: log("Covid data failed to update, response code {}".format( self.unstable_req.status_code)) time.sleep(30)
def get_matchup(team1, team2): """Gets matchup statistics between two teams from CSGOnuts. Args: team1 (dict): First team. Dict of team from get_yaml("teams"). team2 (dict): Second team. Dict of team from get_yaml("teams"). Raises: TypeError: If team1 or team2 are not dictionaries. Returns: A dictionary with statistics if successful, None otherwise. """ if not team1 or not team2 or ('csgonuts' not in team1 or 'csgonuts' not in team2): return None page = requests.get("http://www.csgonuts.com/history?t1=" + team1['csgonuts'] + "&t2=" + team2['csgonuts']) tree = html.fromstring(page.text) try: # If the two teams have not played against each other. error_message = tree.xpath('(//div[contains(text(), "We have no record of match between")])/text()')[0] return None except IndexError: pass # If we have been redirected (Should only happen if a team does not exist). if page.history: bot.log("page.history is not empty. " + team1['csgonuts'] + " or " + team2['csgonuts'] + " does not exist on csgonuts.") return None matches_played = tree.xpath('(/html/body/div/div[2]/div[2]/div[2]/div[3]/div/div[1]/p[1]/span)/text()')[0] matches_played = re.sub(r'\([^)]*\)', '', matches_played) win_percentage = tree.xpath('(/html/body/div/div[2]/div[2]/div[2]/div[3]/div/div[1]/p[2]/span)/text()')[0] maps = {} # Fetch map statistics for i in range(6): try: map_name = tree.xpath('(/html/body/div/div[2]/div[2]/div[2]/div[3]/div/div[' + str(i + 2) + ']/div[1]/a/span)/text()')[0] map_win = tree.xpath('(/html/body/div/div[2]/div[2]/div[2]/div[3]/div/div[' + str(i + 2) + ']/div[2]/span)/text()')[0] maps.update({map_name: map_win}) except IndexError: break matchup = { 'matches_played': matches_played, 'win_percentage': win_percentage, 'maps': maps } return matchup
def __init__(self, client): self.client = client if os.environ['BOT_TOKEN']: self.headers = { "content-type": "application/json", "authorization": os.environ['BOT_TOKEN'], "user-agent": "COVIDWatchDiscordBot/1.1 Python/3.8 requests/2.23.0" } thread = threading.Thread(target=self.run, args=()) thread.daemon = True thread.start() else: log("No DBL token in preferences, not updating any bot pages.")
def update_players(id = 0): """Updates players and stores them in players.yaml. Data is fetched from HLTV.org. Args: id (int): ID to start incrementing from. Raises: TypeError: If id is not an integer. """ invalid = 0 while invalid < 50: id += 1 page = requests.get("http://www.hltv.org/?pageid=173&playerid=" + str(id)) # Overview page tree = html.fromstring(page.text) name = tree.xpath('(//div[normalize-space(text())="Primary team:"]/../../../div[1]/div[2])/text()')[0] maps_played = tree.xpath('(//div[normalize-space(text())="Maps played"]/../div[2])/text()')[0] if str(name) == "N/A": invalid += 1 continue invalid = 0 page = requests.get("http://www.hltv.org/?pageid=246&playerid=" + str(id)) # Match history page tree = html.fromstring(page.text) # Try/catch block for seeing if the player has a match on record try: latest_match = tree.xpath('(//div[normalize-space(text())="Team1"]/../../div[6]/div/div[1]/a)/text()')[0] except IndexError: # Nope... let's move on to the next player continue # Check if player has played at least one match in 2014 or later if int(maps_played) > 0 and int(latest_match.split()[1]) >= 14: players = get_yaml("players") players.update({id: str(name)}) set_yaml("players", players) bot.log("Added " + str(name))
def set_rid(self, id, channel): ''' Sets the rid and rchannel in the database for later tracking in on_reaction_add. ''' prefix = self.log_prefix + "get() -> " id, channel = str(id), str(channel) rid = self.get("rid")[0][0] query = "UPDATE general SET rid = '{}' WHERE rid = '{}'".format( id, rid) bot.log(prefix + "Updating the variable rid to " + id) self.set(query) rchannel = self.get("rchannel")[0][0] query = "UPDATE general SET rchannel = '{}' WHERE rchannel = '{}'".format( channel, rchannel) self.set(query) bot.log(prefix + "Setting rolemenu id to {}#{}".format(channel, id))
def setup_opus(): print("Configuring Opus...\n") opus_libs = [ 'libopus-0.x86.dll', 'libopus-0.x64.dll', 'libopus-0.dll', 'libopus.so.0', 'libopus.so', 'libopus.0.dylib', 'opus', 'opus.exe' ] if not discord.opus.is_loaded(): for opus_lib in opus_libs: try: discord.opus.load_opus(opus_lib) print("Loaded External Opus Library!\n") break except OSError: pass else: print("Loaded System Opus Library!\n") if not discord.opus.is_loaded(): bot.log("INFO", "Failed to Load Opus.\nPCM Audio will be used instead.")
def get(self, query): ''' Retreives the value from the local database. Table: general ''' if query == "rchannel": query = "SELECT rchannel FROM general;" elif query == "rid": query = "SELECT rid FROM general;" bot.log(self.prefix("get") + query) try: with self.con: data = self.con.execute(query).fetchall() except sl.OperationalError as e: bot.log( self.prefix("get") + "The following query was unsuccessful: {}".format(query), "warning") data = None return data
def update_teams(id = 0): """Updates teams and stores them in teams.yaml. Data is fetched from HLTV.org. Args: id (int): ID to start incrementing from Raises: TypeError: If id is not an integer. """ # TODO: Update this old function. (and update_players()) invalid = 0 while invalid < 50: id += 1 page = requests.get("http://www.hltv.org/?pageid=179&teamid=" + str(id)) tree = html.fromstring(page.text) name = tree.xpath('(//div[contains(text(), "Team stats: ")])/text()')[0].replace("Team stats: ", "").strip() maps_played = tree.xpath('(//div[normalize-space(text())="Maps played"]/../div[2])/text()')[0] if str(name) == "No team": invalid += 1 bot.log("No team found") continue invalid = 0 page = requests.get("http://www.hltv.org/?pageid=188&teamid=" + str(id)) tree = html.fromstring(page.text) latest_match = tree.xpath('(//div[normalize-space(text())="Team1"]/../../div[6]/div/a[1]/div)/text()')[0] # Check if team has played at least one match in 2014 or later. if int(maps_played) > 0 and int(latest_match.split()[1]) >= 14: teams = get_yaml("teams") if id not in teams: teams.update({id: {"names": [str(name)]}}) set_yaml("teams", teams)
def __init__(self, _bot): self.bot = _bot try: with open('dbl-token.txt', 'r') as myfile: dbltoken = myfile.read().replace('\n', '') except: try: dbltoken = os.environ['PATCHYBOT-DBLTOKEN'] except: bot.log( "WARNING", "No DBL Token specified in either a 'dbl-token.txt' file or 'PATCHYBOT-DBLTOKEN' System Environment Variable.\nDisabling discordbots.org API support..." ) return self.token = dbltoken try: self.dblpy = dbl.DBLClient(self.bot, self.token) self.bot.loop.create_task(self.update_stats()) except Exception as e: print("Failed to Initialise Discord Bots API!\n" + str(e))
async def on_message(message): log("Message sent " + message.content) if ' ' in message.content: split_msg = str(message.content).split(' ') for i in range(len(split_msg)): if '' in split_msg: split_msg.remove('') else: split_msg = [message.content] if 'c;' == split_msg[0][0:2].lower(): command = str(split_msg[0][2:]) args = "" for a in split_msg[1:]: args += a + " " ran = False for cmd in registered_commands: if cmd.command == command: ran = True await cmd.run(message, args) if not ran: await message.channel.send(content="Did you mean *`c;help`* ?")
def run(self): log("Update Data daemon started.") while True: payload = {"server_count": len(self.client.guilds)} req = requests.post("https://top.gg/api/bots/{}/stats".format(str(self.client.user.id)), json=payload, headers=self.headers) if 199 < req.status_code < 300: log("Successfully posted '" + str(payload) + "' to TopGG.") else: log("Failed to post guild count to TopGG, response code {}".format(req.status_code)) time.sleep(600) # Run every 10 minutes
async def on_ready(): log("Bot ready") UpdateStatus(client) UpdateTopGG(client)
import bot import browser import argparse if __name__ == "__main__": parser = argparse.ArgumentParser( description="Solve Wizard101 Trivias for free Crowns.") parser.add_argument("--browser", help="Launch browser to manually solve captcha.", action='store_true', required=False) parser.add_argument("--debug", help="Launch solver in debug mode to get trvia questions for database additions.", action='store_true', required=False) parser.add_argument("--headless", help="Launch script headless", action='store_true', required=False) args = parser.parse_args() browser.DEBUG = args.debug browser.HEADLESS = args.headless if args.browser or args.debug or args.headless: browser.main() elif bot.CAPTCHA_API == "": bot.log("No Captcha API specified. Please use in browser mode instead.", "error") else: bot.main()
def run(self): log("Update Status daemon started.") state = 5 while True: if state == 1: state = 2 async def update(): try: await self.client.change_presence( activity=discord.Game(name='{:,} Deaths'.format( int(self.covidData.results['Global'] ['TotalDeaths'])))) except: log("Failed to update bot status") asyncio.run(update()) elif state == 2: state = 3 async def update(): try: await self.client.change_presence( activity=discord.Game( name='{:,} Recoveries'.format( int(self.covidData.results['Global'] ['TotalRecovered'])))) except: log("Failed to update bot status") asyncio.run(update()) elif state == 3: state = 4 async def update(): try: await self.client.change_presence( activity=discord.Game(name='{:,} Cases'.format( int(self.covidData.results['Global'] ['TotalConfirmed'])))) except: log("Failed to update bot status") asyncio.run(update()) elif state == 4: state = 5 async def update(): try: await self.client.change_presence( activity=discord.Activity( name="c;help", type=discord.ActivityType.listening)) except: log("Failed to update bot status") asyncio.run(update()) elif state == 5: state = 1 async def update(): try: await self.client.change_presence( activity=discord.Activity( name="{} servers".format( len(self.client.guilds)), type=discord.ActivityType.watching)) except: log("Failed to update bot status") asyncio.run(update()) time.sleep(4)
import Commands.image import Commands.quote import Commands.search import Commands.cards import Commands.music #Commands# try: with open('token.txt', 'r') as myfile: token = myfile.read().replace('\n', '') except: try: token = os.environ['PATCHYBOT-TOKEN'] except: bot.log( "CRITICAL ERROR", "No Bot Token specified in either a 'token.txt' file or 'PATCHYBOT-TOKEN' System Environment Variable.\nBot cannot start." ) raise SystemExit(0) bot.startTime = time() #if not os.path.exists(os.path.dirname(os.path.realpath(__file__)) + '\\temp_music\\'): #os.makedirs(os.path.dirname(os.path.realpath(__file__)) + '\\temp_music\\') bot.cooldown_message = "Hey, slow down! I can only work so fast on my own you know!" if datetime.now().month == 12: if datetime.now().day <= 25: bot.season = "christmas" else:
def main(): """CSGO_Bot's main function. This script is called every 5 minutes through cron. """ oauth = configparser.ConfigParser() oauth.read(__location__ + 'oauth.ini') players = get_yaml("players") teams = get_yaml("teams") bot.log("Players and teams loaded.") # Connect to reddit with praw, set oauth info. r = praw.Reddit("CSGO Competitive Stats Bot v" + __version__, oauth_client_id = oauth['OAuth']['client_id'], oauth_client_secret = oauth['OAuth']['client_secret'], oauth_redirect_uri = oauth['OAuth']['redirect_uri'] ) # OAuth access information. https://github.com/xoru/easy-oauth access_information = { 'access_token': oauth['OAuth']['access_token'], 'refresh_token': oauth['OAuth']['refresh_token'], 'scope': oauth['Scope'] } # Update access_token with our permanent refresh_token. access_information = r.refresh_access_information(access_information['refresh_token']) r.set_access_credentials(**access_information) # Load posts, comments, and messages posts = r.get_subreddit(subreddit).get_new(limit = 20) comments = r.get_comments(subreddit, limit = 100) messages = r.get_messages(limit = 15) bot.log("Looking at messages") for message in messages: if not file_string_exists('messages.txt', message.id): # If we haven't already dealt with this message if message.subject == "COMMAND: No PM": file_string_append('nopm.txt', message.author.name) r.send_message(message.author.name, "Command successful", "You will no longer receive edit confirmation messages.\n\n---\n^(This was an automated message. Regret your decision already? Click) ^[here](http://www.reddit.com/message/compose/?to=CSGO_Bot&subject=COMMAND:%20PM&message=Do%20not%20change%20the%20subject%20text,%20just%20click%20send.) ^(to turn edit confirmation messages back on again.)") bot.log("Added " + message.author.name + " to nopm.txt") elif message.subject == "COMMAND: PM": file_string_remove('nopm.txt', message.author.name) r.send_message(message.author.name, "Command successful", "You will now receive edit confirmation messages.\n\n---\n^(This was an automated message. Regret your decision already? Click) ^[here](http://www.reddit.com/message/compose/?to=CSGO_Bot&subject=COMMAND:%20No%20PM&message=Do%20not%20change%20the%20subject%20text,%20just%20click%20send.) ^(to turn edit confirmation messages back off again.)") bot.log("Deleted " + message.author.name + " from nopm.txt") file_string_append('messages.txt', message.id) # Mark message as done. bot.log("Looking at posts") for post in posts: if (post.link_flair_text == "Match" or post.link_flair_text == "Match has started") and "|" in post.title: if not file_string_exists("posts.txt", post.id): found_teams = find_teams(post.title, teams, False) found_players = find_players(post.selftext, players) poll_teams = [teams[team]['names'][0] for team in found_teams] strawpoll = create_poll(poll_teams) reply = construct_comment(found_teams, found_players, teams, players, strawpoll, True) # Add comment to thread added_comment = post.add_comment(reply) bot.log("Added comment to " + post.id) # Store post id file_string_append("posts.txt", post.id) # Add reply information replies = get_yaml("replies") replies.update({added_comment.id: { 'players': found_players, 'teams': found_teams, 'strawpoll': strawpoll }}) set_yaml("replies", replies) bot.log("Looking at comments") for comment in comments: if not file_string_exists("comments.txt", comment.id): # Skip comment if it doesn't mention us, or if ignore command is used. if "u/csgo_bot" not in comment.body.lower() or "+ignore" in comment.body.lower(): continue # Skip comment if it is deleted. if comment.body == None or comment.author == None: continue # Let's not reply to ourselves or ignored users. if comment.author.name == "CSGO_Bot" or file_string_exists("ignored.txt", comment.author.name): continue # Skip comments that have both remove and add commands. if ("+p" in comment.body.lower() and "-p" in comment.body.lower()) or ("+t" in comment.body.lower() and "-t" in comment.body.lower()): continue case_sensitivity = False remove_players = False remove_teams = False found_players = [] found_teams = [] activated_commands = [] if "+case" in comment.body.lower(): case_sensitivity = True activated_commands.append("+case") # Both +p and -p have to use the find_players function to detect players, so let's deal with them both here. if "+p" in comment.body.lower() or "-p" in comment.body.lower(): found_players = find_players(comment.body, players, case_sensitivity) if "-p" in comment.body.lower(): # Mark the players we just found as ones we want to remove. remove_players = True activated_commands.append("-p") else: activated_commands.append("+p") if "+t" in comment.body.lower() or "-t" in comment.body.lower(): found_teams = find_teams(comment.body, teams, False) if "-t" in comment.body.lower(): remove_teams = True activated_commands.append("-t") else: activated_commands.append("+t") if found_players or found_teams: if "+reply" not in comment.body.lower() and comment.is_root == False: parent = r.get_info(thing_id=comment.parent_id) if parent.author and parent.author.name == "CSGO_Bot": replies = get_yaml("replies") parent_players = replies[parent.id]['players'] parent_teams = replies[parent.id]['teams'] strawpoll = replies[parent.id]['strawpoll'] final_players = None final_teams = None player_difference = False team_difference = False if found_players: if remove_players: final_players = [player for player in parent_players if player not in found_players] else: # Merge lists together (No duplicates) final_players = list(set(parent_players) | set(found_players)) if parent_players != final_players: player_difference = True else: final_players = parent_players if found_teams: if remove_teams: final_teams = [team for team in parent_teams if team not in found_teams] else: final_teams = list(set(parent_teams) | set(found_teams)) # Check if we need to create a new strawpoll if parent_teams != final_teams: parent_teams = final_teams team_difference = True poll_teams = [teams[team]['names'][0] for team in final_teams] strawpoll = create_poll(poll_teams) else: final_teams = parent_teams # Only edit the comment if there is a difference between the old and new one. if player_difference or team_difference: reply = construct_comment(final_teams, final_players, teams, players, strawpoll, True, comment.author.name) # Edit the parent comment with the new information. parent.edit(reply) bot.log("Edited " + parent.id + " from " + comment.id + " (" + comment.author.name + ")") file_string_append("comments.txt", comment.id) # Update reply information. replies = get_yaml("replies") replies.update({parent.id: { 'players': final_players, 'teams': final_teams, 'strawpoll': strawpoll }}) set_yaml("replies", replies) # If the commenter wants to recieve edit-PMs if not file_string_exists('nopm.txt', comment.author.name): message = "[Link](" + parent.permalink + ")\n\nActivated commands: " + ", ".join(activated_commands) + "\n\n" if player_difference: message += "Players detected: " # Find out which players are added/removed if remove_players: affected_players = found_players else: affected_players = [player for player in found_players if player not in parent_players] bot.log("New players: " + str(affected_players)) message += ", ".join("[" + players[player] + "](http://www.hltv.org/?pageid=173&playerid=" + str(player) + ")" for player in affected_players) + "\n\n" if team_difference: message += "Teams detected: " # Find out which teams are added/removed if remove_teams: affected_teams = found_teams else: affected_teams = [team for team in found_teams if team not in parent_teams] bot.log("Found teams: " + str(affected_teams)) message += ", ".join("[" + teams[team]['names'][0] + "](http://www.hltv.org/?pageid=179&teamid=" + team + ")" for team in affected_teams) + "\n\n" message += "---\n^(This was an automated message. If you don't want to receive confirmation on summoning, click) ^[here](http://www.reddit.com/message/compose/?to=CSGO_Bot&subject=COMMAND:%20No%20PM&message=Do%20not%20change%20the%20subject%20text,%20just%20click%20send.)." r.send_message(comment.author.name, "Edit successful", message) bot.log("Sent confirmation message to " + comment.author.name) else: poll_teams = [teams[team]['names'][0] for team in found_teams] strawpoll = create_poll(poll_teams) # Don't make strawpolls for comment replies reply = construct_comment(found_teams, found_players, teams, players, None, False, comment.author.name) added_comment = comment.reply(reply) file_string_append("comments.txt", comment.id) replies = get_yaml("replies") replies.update({added_comment.id: { 'players': found_players, 'teams': found_teams }}) set_yaml("replies", replies)
async def send(channel): ''' Send the pre-defined embed to the designated channel. ''' bot.log("Generating the rolemenu") await channel.send(embed=embed)
message += "---\n^(This was an automated message. If you don't want to receive confirmation on summoning, click) ^[here](http://www.reddit.com/message/compose/?to=CSGO_Bot&subject=COMMAND:%20No%20PM&message=Do%20not%20change%20the%20subject%20text,%20just%20click%20send.)." r.send_message(comment.author.name, "Edit successful", message) bot.log("Sent confirmation message to " + comment.author.name) else: poll_teams = [teams[team]['names'][0] for team in found_teams] strawpoll = create_poll(poll_teams) # Don't make strawpolls for comment replies reply = construct_comment(found_teams, found_players, teams, players, None, False, comment.author.name) added_comment = comment.reply(reply) file_string_append("comments.txt", comment.id) replies = get_yaml("replies") replies.update({added_comment.id: { 'players': found_players, 'teams': found_teams }}) set_yaml("replies", replies) if __name__ == "__main__": try: main() bot.log("Done!") sys.exit(1) except KeyboardInterrupt: bot.log("Forcefully quit.") sys.exit(1)