Esempio n. 1
0
    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)
Esempio n. 2
0
 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))
Esempio n. 3
0
    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()
Esempio n. 4
0
    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
Esempio n. 5
0
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
Esempio n. 6
0
 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)
Esempio n. 7
0
 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()
Esempio n. 8
0
 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")
Esempio n. 9
0
 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")
Esempio n. 10
0
 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()
Esempio n. 11
0
 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)
Esempio n. 12
0
    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)
Esempio n. 13
0
 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}
Esempio n. 14
0
 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)
Esempio n. 15
0
    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)
Esempio n. 16
0
    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()
Esempio n. 17
0
 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])
Esempio n. 18
0
    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()
Esempio n. 19
0
    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")
Esempio n. 20
0
    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
Esempio n. 21
0
 def make_help(self, name, docstring):
     description = '%s Help\n' % name
     em = embed.create_embed(title=description,
                             description=docstring,
                             colour=0xff00ff)
     return em