def get_new_upload(self, uploads_id): '''(scraperyt Plugin, dict) -> discord.Embed Generates an embed about the newest upload from channel info''' upload_items = json.loads( requests.get(self.UPLOADS_ITEM_URL + uploads_id).text) newest_upload = upload_items['items'][0] title = newest_upload['snippet']['title'] description = newest_upload['snippet']['description'].split('\n')[0] image = { 'url': newest_upload['snippet']['thumbnails']['maxres']['url'] } author = { 'name': title, 'url': self.VIDEO_URL_START + newest_upload['snippet']['resourceId']['videoId'], 'icon_url': YOUTUBE_LOGO } footer = { 'text': newest_upload['snippet']['channelTitle'], 'icon_url': None } return embed.create_embed(description=description, image=image, author=author, footer=footer)
def on_plugin_error(self, cmd_name, error): package = self.get_package(cmd_name, self.bot.PLUGINS) if not package: type = self.public_namespace.PLUGINS name = cmd_name else: type = self.public_namespace.PACKAGES name = package if name not in self.public_namespace.commanders[type]: commanders2 = self.public_namespace.generate_commanders(self.bot) self.public_namespace.merge_commanders(commanders2) user_id = self.public_namespace.commanders[type][name][ self.public_namespace.OWNER] user = discord.utils.find(lambda u: u.id == user_id, self.bot.get_all_members()) if user: tb = self.make_traceback(error) title = '**%s** (plugin) raised an exception during execution' % cmd_name desc = '```' + tb + '```' footer = { 'text': 'You are receiving this because you are the registered owner of this %s' % type[:-1], 'icon_url': None } em = embed.create_embed(footer=footer, title=title, description=desc, colour=0xff1111) self.bot.loop.create_task(self.send_message(user, embed=em))
async def action(self): try: # used to reset stuff while developing # (edit_message does weird stuff sometimes) # await self.edit_message(self.message, embed=embed.create_embed(description='')) if not self.startup_time_seconds: self.startup_time_seconds = time.perf_counter() # create embed description description = "" description += "**Servers** : %s \n" % len(self.bot.servers) description += "**Messages seen** : %s \n" % len(self.bot.messages) description += "**Messages watched** : %s \n" % len( self.bot.always_watch_messages) description += "**Users** : %s \n" % discordstats.total_users( self.bot) description += " - - - - - - - - - - - - - - - - - - - - - - \n" # seperator description += "**Plugins** : %s \n" % len(self.bot.plugins) description += "**Commands** : %s \n" % len(self.bot.commands) description += "**Reactions** : %s \n" % len(self.bot.reactions) description += " - - - - - - - - - - - - - - - - - - - - - - \n" # seperator description += "**Startup** : %s \n" % self.startup_time.isoformat( ) description += "**Uptime** : %s \n" % str( datetime.datetime.now() - self.startup_time).split('.')[ 0] # uptime, without decimal seconds description += "**Time Leak** : %.8fs \n" % ( (time.perf_counter() - self.startup_time_seconds) % self.period ) # time leak since startup description += "**Idea Size** : %4.2f kB \n" % (get_size() / 1024) description += "***Last Updated*** *: %s* \n" % datetime.datetime.now( ).isoformat() # create embed author author = dict() author[ 'name'] = self.bot.user.name if self.bot.user.name != None else None author['icon_url'] = self.bot.user.avatar_url author[ 'url'] = r'https://github.com/NGnius/IdeaBot' # Remove if perceived as advertising await self.edit_message( self.message, new_content=' ', embed=embed.create_embed(description=description, author=author)) if COLLECT_STATS in self.config: discordstats.dumpMessages(self.bot, filename='./data/msgdump%s.csv' % self.startup_time.isoformat()) except: traceback.print_exc()
def on_reaction_error(self, cmd_name, error, reaction, user): log.error(error) if isinstance(error, discord.DiscordException): keys_list = list(self.bot.reactions.keys()) if cmd_name == keys_list[-1] and 'invalid' in keys_list[-1].lower( ): return log.info("Caught discord exception in %s" % cmd_name) error_msg = self.make_dis_error_str(error, cmd_name) try: yield from self.send_message(reaction.message.channel, error_msg) except discord.Forbidden: try: yield from self.send_message(user, error_msg) except discord.Forbidden: log.warning( "Sending discord error failed during exception in %s" % cmd_name) return package = self.get_package(cmd_name, self.bot.REACTIONS) if not package: type = self.public_namespace.REACTIONS name = cmd_name else: type = self.public_namespace.PACKAGES name = package if name not in self.public_namespace.commanders[type]: commanders2 = self.public_namespace.generate_commanders(self.bot) self.public_namespace.merge_commanders(commanders2) user_id = self.public_namespace.commanders[type][name][ self.public_namespace.OWNER] user = discord.utils.find(lambda u: u.id == user_id, self.bot.get_all_members()) if user: tb = self.make_traceback(error) title = '**%s** (reaction) raised an exception during execution' % cmd_name desc = '```' + tb + '```' footer = { 'text': 'You are receiving this because you are the registered owner of this %s' % type[:-1], 'icon_url': None } em = embed.create_embed(footer=footer, title=title, description=desc, colour=0xff1111) try: yield from self.send_message(user, embed=em) except: traceback.print_exc() pass
def make_embed(addons_dict, colour=0xff00ff): footer = {'text': '@Idea help <item> for more info', 'icon_url': None} desc = '' for key in addons_dict: if key is not None: # display package-less add-ons at the bottom desc += '**' + key + '**' + '\n' desc += process_list(addons_dict[key], prefix='--') desc += '**' + '[NO PACKAGE]' + '**' + '\n' desc += process_list(addons_dict[None], prefix='--') em = embed.create_embed(description=desc, footer=footer, colour=colour) return em
def action(self, message): args = re.search(r'\bspoiler\s([\d]{1,2})', message.content, re.I) msgEmbed = embed.create_embed(title="SPOILERS!", author={ "name": "River Song", "url": None, "icon_url": None }, description=int(args.group(1)) * ".\n" + "^^^ WARNING: Spoiler Above ^^^") yield from self.send_message(message.channel, embed=msgEmbed)
def action(self, message): description='**Future location of a server status message**' footer=dict() footer['text'] = '(Unofficial) CardLife API' footer['icon_url'] = None em = embed.create_embed(description=description, footer=footer) try: msg = yield from self.send_message(message.channel, embed=em) except discord.errors.DiscordException: yield from self.send_message(message.channel, 'Failed to create embed here, please make sure I have permission to embed links & stuff.') self.public_namespace.messages[msg.id]=msg.channel.id self.public_namespace.messages_file.content=self.public_namespace.messages self.public_namespace.messages_file.save()
def close_poll(self, message, send_func, poll_name): '''(EndVoteCommand, discord.Message, func, str) -> None ''' poll = self.find_poll_id(poll_name) if poll!=None: dump = self.vote_dict[poll][VOTES].dumpVotes() tally = self.vote_dict[poll][VOTES].tallyVotes() description = self.format_results(tally) if '-v' in message.content.lower(): description_v = self.format_dump(dump) if '--public' in message.content.lower(): yield from send_func(message.channel, embed=embed.create_embed(title=self.vote_dict[poll][NAME], description=description_v, footer={"text":"Votes (verbose mode)", "icon_url":None}, colour=0xeeee00)) else: yield from send_func(message.author, embed=embed.create_embed(title=self.vote_dict[poll][NAME], description=description_v, footer={"text":"Votes (verbose mode)", "icon_url":None}, colour=0xeeee00)) yield from send_func(message.channel, embed=embed.create_embed(title=self.vote_dict[poll][NAME], description=description, footer={"text":"Voting ended", "icon_url":None}, colour=0xee3333)) del(self.vote_dict[poll]) # remove message from always_watch_messages for item in self.always_watch_messages: if not isinstance(item, str): # ignore loading warning str if item.id == poll: self.always_watch_messages.remove(item) break else: yield from send_func(message.channel, "Invalid ID or name")
def action(self, message, send_func): args = re.search(r'\b(end)\s+["]([^"]+)["]+\s+\b(vote)', message.content, re.I) #group(1) is end, group(2) is vote name, group(3) is vote if args.group(2) in self.vote_dict: yield from send_func( message.channel, embed=embed.create_embed( title=self.vote_dict[args.group(2)][NAME], description=self.format_results( self.vote_dict[args.group(2)][VOTES].tallyVotes()), footer={ "text": "Voting ended", "icon_url": None }, colour=0xee3333)) del (self.vote_dict[args.group(2)]) else: found = False for poll in self.vote_dict: if args.group(2) == self.vote_dict[poll][NAME]: found = True yield from send_func( message.channel, embed=embed.create_embed( title=self.vote_dict[poll][NAME], description=self.format_results( self.vote_dict[poll][VOTES].tallyVotes()), footer={ "text": "Voting ended", "icon_url": None }, colour=0xee3333)) del (self.vote_dict[poll]) break if not found: yield from send_func(message.channel, "Invalid ID or name")
def threaded_action(self, q, newGCal=plugin.Queue()): # handle new items from url_adder while not newGCal.empty(): item = newGCal.get() item["id"]=item["id"].split('%40group.calendar.google.com')[0] item["id"]=item["id"]+"@group.calendar.google.com" if item["action"] == "remove" or item["action"] == "delete": try: del(self.data.content[item["id"]][self.CHANNELS][self.data.content[item["id"]][self.CHANNELS].index(item[self.CHANNEL])]) except (TypeError, KeyError, ValueError, NameError): # traceback.print_exc() pass elif item["action"]=="add": if item["id"] not in self.data.content: self.data.content[item["id"]]={self.CHANNELS:list(), self.SEEN:list()} # dict self.data.content[item["id"]][self.CHANNELS].append(item[self.CHANNEL]) # do scrape things for calendar_id in self.data.content: try: url = (self.config[URL]+calendar_id+r'/events'+'?key='+self.config[TOKEN]+ '&timeMin='+datetime.datetime.utcnow().isoformat()+'Z'+ '&timeMax='+( datetime.datetime.utcnow()+datetime.timedelta(seconds=self.threaded_period) ).isoformat()+'Z'+ '&maxResults=%s' % MAX_RESULTS + '&singleEvents=True&orderBy=startTime') # print(url) events = requests.get(url) events = json.loads(events.text) # print(json.dumps(events, indent=2)) items = events['items'] for item in items: if item['id'] not in self.data.content[calendar_id][self.SEEN]: self.data.content[calendar_id][self.SEEN].append(item['id']) description = '__**%s**__' % item['summary'] if 'dateTime' in item['start']: datething = 'dateTime' else: datething = 'date' description+='\n' + self.process_date(item['start'][datething]) + ' to ' + self.process_date(item['end'][datething]) + ' UTC\n' cal_embed = embed.create_embed( description=description, author={'name':'Google Calendar (Upcoming)', 'url':item['htmlLink'], 'icon_url':GOOGLE_LOGO}, footer={'text':item['organizer']['displayName'], 'icon_url':None} ) for discord_channel in self.data.content[calendar_id][self.CHANNELS]: q.put({self.SEND_MESSAGE:{plugin.ARGS:[discord.Object(id=discord_channel)], plugin.KWARGS:{'embed':cal_embed}}}) except: # TODO: log request failure # print('Failed on %s' %calendar_id) # traceback.print_exc() pass self.data.save()
def action(self, reaction, user): em = embed.create_embed(author={ "name": reaction.message.author.display_name, "url": None, "icon_url": None }, footer={ "text": "#" + reaction.message.channel.name + " of " + reaction.message.server.name, "icon_url": None }, description=reaction.message.content, colour=0xeeeeee) yield from self.send_message(reaction.message.channel, embed=em)
def get_new_milestone(self, channel_dict, channel_id): '''(scraperyt Plugin, dict) -> discord.Embed Generates an embed about the subscriber milestone from channel info''' channel = channel_dict['items'][0] message = channel['snippet'][ 'title'] + " has reached %s subscribers!" % 10**self.data.content[ channel_id][SUB_MILESTONE] footer = {'text': channel['snippet']['title']} # unused author = { 'name': channel['snippet']['title'], 'url': self.CHANNEL_URL_START + channel['id'], 'icon_url': YOUTUBE_LOGO } image = {'url': channel['snippet']['thumbnails']['default']['url']} return embed.create_embed(description=message, author=author, image=image)
def gen_message(self, message): if self.style == self.DEFAULT: return [message.content], {'embed': None} if self.style == self.EMBED: em = em = embed.create_embed(author={ "name": message.author.display_name, "url": None, "icon_url": message.author.avatar_url }, footer={ "text": "#" + message.channel.name + " of " + message.server.name, "icon_url": None }, description=message.content, colour=0xeeeeee) return [], {'embed': em}
def action(self, message): quotedMessage = eval( dataloader.datafile( self.saveloc + "/" + re.search(r'(\d{18})', message.content).group(1) + ".txt").content[0]) em = embed.create_embed(author={ "name": quotedMessage["author"], "url": None, "icon_url": None }, footer={ "text": "#" + quotedMessage["channel"] + " of " + quotedMessage["server"], "icon_url": None }, description=quotedMessage["content"], colour=0xffffff) yield from self.send_message(message.channel, embed=em)
def action(self, message): yield from self.send_typing(message.channel) try: # cardlife REST API queries # login to CardLife to get PublicId auth = requests.post( "https://live-auth.cardlifegame.com/api/auth/authenticate", json={ "EmailAddress": self.config["email"], "Password": self.config["password"] }) auth_json = auth.json() # get information about all servers lobby = requests.post( 'https://live-lobby.cardlifegame.com/api/client/games', json={"PublicId": auth_json["PublicId"]}) lobby_json = lobby.json() except: # catch server errors # TODO: log failed server requests yield from self.send_message(message.channel, 'Unable to contact CardLife servers') return args = self.collect_args(message) name_id = args.group(1) # server name OR id server_info = self.find_name_or_id(name_id, lobby_json['Games']) # print(server_info) if server_info == None: yield from self.send_message( message.channel, 'Unable to find `%s`, maybe it\'s offline?' % name_id) return # fix for ModInfo returned as string instead of dict if isinstance(server_info['ModInfo'], str): server_info['ModInfo'] = json.loads(server_info['ModInfo']) # format server_info nicely is_modded = len(server_info['ModInfo']['orderedMods']) > 0 description = '**' if server_info['IsOfficial'] == True: description += 'Official ' elif server_info['IsOfficial'] == False: description += 'Unofficial ' if is_modded: description += 'modded ' if server_info['IsPvp'] == True: description += 'PVP ' elif server_info['IsPvp'] == False: description += 'PVE ' description += 'server**\n' if is_modded: # description+='Mods: `' field_val3 = '' for mod in server_info['ModInfo']['orderedMods']: field_val3 += mod['name'] if mod['metadata']['author']: field_val3 += ' by ' + mod['metadata']['author'] field_val3 += '\n' field_val3 = field_val3 # description=description[:-2]+'`\n' description_end = \ '''`{CurrentPlayers}/{MaxPlayers}` online @ {Ping}ms Region: {0} AntiCheat: {IsAntiCheatEnabled} Password: {HasPassword} `v{GameVersion}` | ID:`{Id}`''' # description += description_end.format(server_info["Region"].upper(), **server_info) server_info["Region"] = server_info["Region"].upper() if str(server_info['Id']) in self.public_namespace.uptime: seen, total = self.public_namespace.uptime[str(server_info['Id'])][ self.public_namespace. SEEN_TIMES], self.public_namespace.uptime[str( server_info['Id'])][self.public_namespace.TOTAL_TIMES] server_info["Uptime"] = (seen / total) else: server_info["Uptime"] = 1 # Connection info field_val1 = '''Players: `{CurrentPlayers}/{MaxPlayers}` Uptime: `{Uptime:.0%}` Ping: {Ping}ms Region: {Region} ''' field_val1 = field_val1.format(**server_info) # Security info field_val2 = '''AntiCheat: {IsAntiCheatEnabled} Password: {HasPassword} ''' field_val2 = field_val2.format(**server_info) # Debug info field_val4=\ '''ID:`{Id}` `v{GameVersion}` ''' field_val4 = field_val4.format(**server_info) footer = dict() footer['text'] = '(Unofficial) CardLife API' footer['icon_url'] = None em = embed.create_embed(title='' + server_info['WorldName'] + '', description=description, footer=footer, colour=0xddae60) em.add_field(name='Server Online', value=field_val1, inline=True) em.add_field(name='Security', value=field_val2, inline=True) if is_modded: em.add_field(name='Mods', value=field_val3, inline=True) em.add_field(name='Debug', value=field_val4, inline=is_modded) yield from self.send_message(message.channel, embed=em)
def threaded_action(self, q, newForum=plugin.Queue(), **kwargs): # handle new items from url_adder while not newForum.empty(): item = newForum.get() if item["action"] == "remove" or item["action"] == "delete": try: del (self.data.content[item["url"]][self.CHANNELS][ self.data.content[item["url"]][self.CHANNELS].index( item[self.CHANNEL])]) if self.data.content[item["url"]][self.CHANNELS] == list(): del (self.data.content[item["url"]]) except (TypeError, KeyError, ValueError, NameError): # traceback.print_exc() pass elif item["action"] == "add": forumLog.debug("Adding " + item['url']) if not item['url'].endswith(r"/rss/public"): item['url'].strip(r"/") item['url'] += r"/rss/public" if item["url"] not in self.data.content: self.data.content[item["url"]] = { self.CHANNELS: list(), self.MOST_RECENT: self.FIRST } # dict self.data.content[item["url"]][self.CHANNELS].append( item[self.CHANNEL]) # do scrape things for forum in self.data.content: forumLog.debug("Now scraping %s" % forum) mostrecentrunstart = time.time() try: rss = BeautifulSoup( pageRet.pageRet(forum).decode(), "html.parser") # landing page items = rss.find_all("item") threads = [[ x.find("guid").get_text(), x.find("title").get_text() ] for x in items] # list of [url, thread title] if self.is_new_thread(threads[0][0], forum): newestint = self.get_trailing_int( self.get_most_recent(forum)) if self.get_most_recent(forum) == self.FIRST: threads = [threads[0]] for i in threads: if self.get_trailing_int(i[0]) > newestint: forumLog.debug("New thread found: " + i[0]) #scrape stuff recentThread = BeautifulSoup( pageRet.pageRet(i[0]).decode(), "html.parser") authors = [] for x in recentThread.find_all( "div", class_="mini-profile"): try: authors.append({ "name": x.find("a").get_text(), "url": x.find("a").get("href"), "img": x.find("div", class_="avatar").find( "img").get("src") }) except AttributeError: # if author is a guest, x.find("a") will return a NoneType, and None.get("href") will raise an AttributeError pass #authors = [x.find("a").get("href") for x in recentThread.find_all("div", class_="mini-profile")] thread = [i[0], authors] for discord_channel in self.data.content[forum][ self.CHANNELS]: q.put({ self.SEND_MESSAGE: { plugin.ARGS: [discord.Object(id=discord_channel)], plugin.KWARGS: { 'embed': embed.create_embed( description="In: " + thread[0], author={ "name": thread[1][-1]["name"], "url": forum + thread[1][-1]["url"], "icon_url": None }, footer={ "text": "Forum", "icon_url": None }) } } }) # q.put([i[0], authors]) else: break # self.delete_entry("most recent thread:", forum) self.data.content[forum][self.MOST_RECENT] = threads[0][0] forumLog.debug("Most recent thread is now: " + threads[0][0]) forumLog.debug("Finished scraping run in " + str(time.time() - mostrecentrunstart)) except: # Prevent a failed run from crashing the whole thread # traceback.print_exc() forumLog.warning( "Scraping run failed for %s. Either the page has changed or the page is unavailable..." % forum) self.data.save()
def action(self, message): args = self.collect_args(message) op_flag = '' msg_content = None # determine operation operation = args.group(1).lower() if args.group(1) is not None else '' if operation in todo_rm_words: op_flag = 'remove' elif operation in todo_add_words: op_flag = 'add' elif operation in todo_list_words: op_flag = 'list' else: if args.group(2): op_flag = 'add' else: op_flag = 'list' # determine if public list list_name = message.author.id task = args.group(2).strip() if args.group(2) is not None else '' if args.group(2): list_args = self.collect_list(args.group(2)) if list_args and not is_id_like(list_args.group(1)): list_name = list_args.group(1) task = args.group(2).replace(list_args.group(0), '') elif op_flag == 'add' or op_flag == 'remove': yield from self.send_message( message.channel, 'Please specify the task to %s' % op_flag) return # load files if they don't already exist if list_name not in todoFiles: try: todoFiles[list_name] = dataloader.datafile(self.saveloc + list_name + ".txt") except FileNotFoundError: todoFiles[list_name] = dataloader.newdatafile(self.saveloc + list_name + ".txt") # add task if op_flag == 'add': # TODO: check for permissions to edit list_name before adding task index = self.get_index_for_task(task, todoFiles[list_name]) if index != -1 and re.match(r'^\d+$', task) != None: msg_content = "I'm sorry, `%s` already exists" % task else: todoFiles[list_name].content.append(task) msg_content = "Task added" # remove task if op_flag == 'remove': # TODO: check for permissions to edit list_name before removing task index = self.get_index_for_task(task, todoFiles[list_name]) if index == -1 or index >= len(todoFiles[list_name].content): msg_content = "I'm sorry, I can't find `%s`." % task else: del (todoFiles[list_name].content[index]) todoFiles[list_name].save() msg_content = "Task deleted" # always list tasks after everything list_display_name = list_name if list_name != message.author.id else 'Todo' if re.search(r'\s-p', message.content, re.I) != None or list_name != message.author.id: yield from self.send_message(message.channel, msg_content, embed=embed.create_embed( title=list_display_name, description=self.todo2string( todoFiles[list_name]), colour=0xffffff)) else: yield from self.send_message(message.author, msg_content, embed=embed.create_embed( title=list_display_name, description=self.todo2string( todoFiles[list_name]), colour=0xffffff)) # save file todoFiles[list_name].save() # remove file from memory if empty, to save some memory if len(todoFiles[list_name].content) == 0: del (todoFiles[list_name])
def threaded_action(self, q, newTwit=plugin.Queue(), **kwargs): '''(ThreadedPlugin, Queue ) -> None Checks continuously for new tweets from the official twitter. This should be run in a different thread since it is blocking (it's a while loop ffs)''' # handle new items from url_adder while not newTwit.empty(): item = newTwit.get() item['url']=item['url'].strip('/').lower() if item["action"] == "remove" or item["action"] == "delete": try: del(self.data.content[item["url"]][self.CHANNELS][self.data.content[item["url"]][self.CHANNELS].index(item[self.CHANNEL])]) if self.data.content[item["url"]][self.CHANNELS] == list(): del(self.data.content[item["url"]]) except (TypeError, KeyError, ValueError, NameError): # traceback.print_exc() pass elif item["action"]=="add": twitLog.debug("Adding "+item['url']) if item["url"] not in self.data.content: self.data.content[item["url"]]={self.CHANNELS:list(), self.MOST_RECENT:self.FIRST, self.MOST_RECENT2:self.FIRST} # dict self.data.content[item["url"]][self.CHANNELS].append(item[self.CHANNEL]) # do scrape things for twitAccount in self.data.content: # twitAccount is the user's account URL twitLog.debug("Now scraping "+twitAccount) mostrecentrunstart = time.time() try: author = self.get_twitter_user_from_url(twitAccount) twitLog.debug("URL: "+RSS_URL_START+author) rss = BeautifulSoup(pageRet.pageRet(RSS_URL_START+author).decode(), "html.parser") # rss page items = rss.find_all("item") #print(items) tweets = [[self.get_url(x), self.get_tweet(x), x] for x in items] # create list of [url to tweet, tweet content] pinned_tweet = tweets[0] tweets = tweets[1:] # remove first tweet since it's pinned if len(tweets)>1 and self.is_new_tweet(tweets[0][0], twitAccount) and self.is_new_tweet(tweets[1][0], twitAccount, second=True): if self.data.content[twitAccount][self.MOST_RECENT]==self.FIRST: tweets=tweets[0:2] for i in tweets: if self.is_new_tweet(i[0], twitAccount): twitLog.debug("New tweet found: " + i[0]) tweet_author = self.get_author(i[2]) tweet = {"url":i[0], "content":i[1], "author":tweet_author, "retweet":False} # search for picture in content img_link = self.get_image(i[2]) img=None if img_link is not None: # set pic img = {'url':img_link} tweet['content']=tweet['content'].replace(img_link, '') tweet['content']=re.sub(r'pic\.twitter\.com/([\w\d]+)', '', tweet['content'], re.I) if author.lower() != tweet_author.lower(): tweet["retweet"] = True em = embed.create_embed(image=img, author={"name":author+" retweeted "+tweet["author"], "url":tweet["url"], 'icon_url':None}, description=tweet["content"], footer={"text":"Twitter", "icon_url":TWITTER_LOGO}) else: good_author=tweet["author"] em = embed.create_embed(image=img, author={"name":good_author, "url":tweet["url"], 'icon_url':None}, description=tweet["content"], footer={"text":"Twitter", "icon_url":TWITTER_LOGO}) for discord_channel in self.data.content[twitAccount][self.CHANNELS]: params= {self.SEND_MESSAGE:{plugin.ARGS:[discord.Object(id=discord_channel)], plugin.KWARGS:{'embed':em}}} q.put(params) #q.put(q_entry) else: break # self.delete_entry("most recent tweet:") if good_author!= author: # fix author capitalisation if necessary good_twitAccount = twitAccount.replace(author, good_author) self.data.content[good_twitAccount] = self.data.content[twitAccount] self.data.content[twitAccount] = None del(self.data.content[twitAccount]) twitAccount = good_twitAccount self.data.content[twitAccount][self.MOST_RECENT]=tweets[0][0] self.data.content[twitAccount][self.MOST_RECENT2]=tweets[1][0] twitLog.debug("Most recent tweet is now: " + tweets[0][0]) twitLog.debug("Second most recent tweet is now: " + tweets[1][0]) twitLog.debug("Finished scraping run in "+ str(time.time() - mostrecentrunstart)) except: # Prevent a failed run from crashing the whole thread twitLog.warning("Scraping run failed. Either the page has changed or the page is unavailable...") # traceback.print_exc() self.data.save()
def action(self, message, send_func): reply = "" temp_dict = dict() mode = re.compile(r'\bmode[:=]?\s*([^\s]+)\s*', re.I).search(message.content) if mode == None or mode.group(1).strip( "\'\"").lower() not in VALID_MODES: reply += 'Choosing default mode. Set a mode by putting `mode` in front of a valid mode, like `mode: stp ` or `mode fptp ` \n' temp_dict[MODE] = DEFAULT_MODE else: temp_dict[MODE] = mode.group(1).strip("\'\"").lower() reply += 'Mode set to ' + temp_dict[MODE] + "\n" name = re.compile(r'\bname[:=]?\s*["]([^"]+)["]', re.I).search(message.content) name_is_used = False if name != None and name.group(1) != "": for poll in self.vote_dict: if self.vote_dict[poll][NAME] == name.group(1): name_is_used = True break if name == None or name.group(1) == "" or name_is_used: reply += 'Name conflict or no name declared. Choosing default name. Set a unique name by putting `name` in front of a name, surrounded by quotes, like `name \"My Cool Poll\"` or `name:\"Awesome Poll Name\"` \n' temp_dict[NAME] = str(DEFAULT_NAME_GEN()) else: temp_dict[NAME] = name.group(1) reply += 'Name set to ' + temp_dict[NAME] + "\n" options = re.compile(r'\boptions?[:=]?\s*((["][^"]+["][\s,]*)+)', re.I).search(message.content) if options == None: reply += 'Choosing default options. Set options by putting `options` in front of options surrounded by quotes, like `options: \"Idea\" \"Project\" \"Channel\"` or `option\"Mace\"\"Flash\"\"Mike\"\"NG\"` \n' options = DEFAULT_OPTIONS else: options = options.group(1).split('\"') options = [options[i] for i in range(len(options)) if i % 2 == 1] reply += 'Options set to ' + str(options) + "\n" if temp_dict[MODE] == "fptp" or temp_dict[MODE] == "": temp_dict[VOTES] = voting.FPTP(options=list(options)) elif temp_dict[MODE] == "stv": try: transferables = int( re.compile(r'\bt[\D]{0,12}[:=]?\s*(\d+)\s*', re.I).search(message.content).group(1)) except: transferables = DEFAULT_TRANSFERABLES reply += "Transferables set to " + str(transferables) temp_dict[VOTES] = voting.STV(options=list(options), transferables=transferables) if reply != "" and (" -v " in message.content.lower() or " -v" == message.content.lower()[-3:]): yield from send_func(message.author, reply) #send error msg (if any) embed_message = yield from send_func( message.channel, embed=embed.create_embed(title=temp_dict[NAME], description="Options: " + str(temp_dict[VOTES].options) + "\nMode: " + temp_dict[MODE], footer={ "text": "Voting started", "icon_url": None }, colour=0x33ee33)) self.vote_dict[embed_message.id] = dict(temp_dict) return if args.group(4) not in self.vote_dict: temp_dict = dict() temp_dict[NAME] = args.group(4) temp_dict[MODE] = args.group(2).lower() if temp_dict[MODE] == "fptp" or temp_dict[MODE] == "": temp_dict[VOTES] = voting.FPTP( options=args.group(6).split(",")) elif temp_dict[MODE] == "stv": temp_dict[VOTES] = voting.STV(options=args.group(6).split(",")) embed_message = yield from send_func( message.channel, embed=embed.create_embed(title=temp_dict[NAME], description="Options: " + str(temp_dict[VOTES].options) + "\nMode: " + temp_dict[MODE], footer={ "text": "Voting started", "icon_url": None }, colour=0x33ee33)) self.vote_dict[embed_message.id] = dict(temp_dict) else: yield from send_func( message.channel, "Name conflict - please choose a different name")
async def action(self): try: # used to reset stuff while developing # (edit_message does weird stuff sometimes) # await self.edit_message(self.message, embed=embed.create_embed(description='')) try: # cardlife REST API queries # login to CardLife to get PublicId auth = requests.post( "https://live-auth.cardlifegame.com/api/auth/authenticate", json={ "EmailAddress": self.config["email"], "Password": self.config["password"] }) auth_json = auth.json() # get information about all servers lobby = requests.post( 'https://live-lobby.cardlifegame.com/api/client/games', json={"PublicId": auth_json["PublicId"]}) servers_json = lobby.json() except: # catch server errors # TODO: log failed server requests # print("Received invalid response from CardLife servers, skipping run...") return # skip run # create embed description self.record_uptime(servers_json["Games"]) title = "CardLife Online Servers (%s)" % len(servers_json["Games"]) description = '' highest_playercount = 0 for item in servers_json['Games']: playercount = '%s/%s' % (item['CurrentPlayers'], item['MaxPlayers']) if len(playercount) > highest_playercount: highest_playercount = len(playercount) # create online server list str online_official_servers = dict() for item in servers_json['Games']: if item['IsOfficial']: online_official_servers[str( item['Id'])] = item['WorldName'] if not item['HasPassword']: # create single line to describe server playercount = '%s/%s' % (item['CurrentPlayers'], item['MaxPlayers']) spaces = highest_playercount - len(playercount) description += '`' + (spaces * '.') + playercount + '`| ' description += '' + item['WorldName'] + '' if len(json.loads(item['ModInfo'])['orderedMods']) != 0: description += ' (**M**)' if item['HasPassword']: # contradiction; will never happen description += ' (**P**)' description += '\n' # create offline official server list offline_servers_str = '' for id in self.official_servers: if id not in online_official_servers: offline_servers_str += '**!** | ' + self.official_servers[ id] + '\n' for id in online_official_servers: self.official_servers[id] = online_official_servers[ id] # update server names if offline_servers_str != '': description += '\n**__Offline__**\n' + offline_servers_str footer = dict() footer['text'] = '(Unofficial) CardLife API' footer['icon_url'] = None em = embed.create_embed(description=description, footer=footer, colour=0xddae60, title=title) deleted_messages = list() # update status messages for msg in self.public_namespace.messages: message = discord.Object(id=msg) message.channel = discord.Object( id=self.public_namespace.messages[msg]) try: await self.edit_message(message, new_content=' ', embed=em) except discord.NotFound: deleted_messages.append( msg) # catch deleted/inaccessible messages except: # don't stop other updates due to one error pass # remove deleted messages for msg in deleted_messages: del (self.public_namespace.messages[msg]) # save modified files self.official_servers_data.content = self.official_servers self.official_servers_data.save() self.public_namespace.messages_file.content = self.public_namespace.messages self.public_namespace.messages_file.save() except: traceback.print_exc() pass
def make_help(self, name, docstring): description = '%s Help\n' % name em = embed.create_embed(title=description, description=docstring, colour=0xff00ff) return em