Beispiel #1
0
    def get_config(self, path_to_pob_conf):
        loaded_conf = None
        file_path = config.ROOT_DIR + path_to_pob_conf
        try:
            loaded_conf = json.load(open(file_path))
        except FileNotFoundError as err:
            log.error(
                f'{path_to_pob_conf} is missing, trying to obtain a new copy... err was "{err}"'
            )

        if loaded_conf:
            week_ago_date = datetime.now() - timedelta(days=7)
            # json_date = datetime.fromisoformat(loaded_conf['utc-date']) todo: enable when pypy 3.7 exists
            json_date = datetime.strptime(loaded_conf['utc-date'],
                                          "%Y-%m-%dT%H:%M:%S.%f")
            # if json date is older than a week, update
            if json_date < week_ago_date:
                self.fetch_config(file_path)
                log.info(
                    f"finished creating new {path_to_pob_conf}.json in resources..."
                )
                loaded_conf = json.load(open(file_path))

        if not loaded_conf:
            self.fetch_config(path_to_pob_conf)
            log.info(
                f"finished creating new {path_to_pob_conf}.json in resources..."
            )
            loaded_conf = json.load(open(file_path))

        return loaded_conf
Beispiel #2
0
    def _parse_pob(author, content, minify=False):
        """
        Trigger the parsing of the pastebin link, pass it to the output creating object and send a message back
        :param minify: show minified version of the embed
        :param content: of the message
        :param author: user sending the message
        :return: Embed
        """
        paste_keys = pastebin.fetch_paste_key(content)
        if paste_keys:
            paste_key = random.choice(paste_keys)
            log.info(f"Parsing pastebin with key={paste_key} from author={author}")
            raw_data = pastebin.get_as_xml(paste_key)
            if not raw_data:
                log.error(f"Unable to obtain raw data for pastebin with key {paste_key}")
                return

            xml = pastebin.decode_to_xml(raw_data)
            if not xml:
                log.error(f"Unable to obtain xml data for pastebin with key {paste_key}")
                return

            web_poe_token = util.fetch_xyz_pob_token(raw_data)
            build = pob_xml_parser.parse_build(xml)
            try:
                embed = pob_output.generate_response(author, build, minified=minify, pastebin_key=paste_key,
                                                     non_dps_skills=poe_consts, web_poe_token=web_poe_token)
                log.debug(f"embed={embed}; thumbnail={embed.thumbnail}")
                return embed
            except Exception as e:
                ex_msg = ''.join(traceback.format_exception(etype=type(e), value=e, tb=e.__traceback__))
                log.error(f"Could not parse pastebin={paste_key} - Exception={ex_msg}")
Beispiel #3
0
    def test_bot_parse_routine(self):
        """
        Tests whether all links inside of the file can be successfully parsed
        """
        links = get_links()
        xml_keys = file_loader.get_pastebin_keys()

        for link in links:
            if "https://pastebin.com/" in link:
                key = link.split("/")[-1]
                if key not in xml_keys:
                    log.warning(f"Downloading xml from pastebin for key={key}")
                    PastebinHelper.fetch_pastebin(key)

        xml_file_paths = file_loader.get_pastebin_file_dir_files()
        for file_path in xml_file_paths:
            test_path = get_test_path(
                os.path.join(file_loader.pastebin_xmls_file, file_path))
            with open(test_path, "r") as f:
                demo_author = None
                log.info(f"Testing whether we can parse '{test_path}'")
                xml_tree = ET.fromstring(f.read())

                build_embed = PoBCog._generate_embed(
                    None, xml_tree, demo_author,
                    f"https://pastebin.com/{file_path.split('.xml')[0]}")
                self.assertTrue(isinstance(build_embed, Embed))
Beispiel #4
0
 def _detect_paste_key(content: str, author):
     paste_key = None
     paste_keys = pastebin.fetch_paste_key(content)
     if paste_keys:
         paste_key = random.choice(paste_keys)
         log.info(
             f"Parsing pastebin with key={paste_key} from author={author}")
     return paste_key
Beispiel #5
0
 def __init__(self, path_to_spectres=POB_SPECTRES):
     file_path = config.ROOT_DIR + path_to_spectres
     try:
         self.spectres = json.load(open(file_path))
     except FileNotFoundError as err:
         log.error(f'{path_to_spectres} is missing, trying to obtain a new copy... err was "{err}"')
         self.fetch_spectres(file_path)
         log.info(f"finished creating new {path_to_spectres} in resources...")
         self.spectres = json.load(open(file_path))
Beispiel #6
0
 async def pob(self, ctx, *, key):
     if not self.allow_pming and ctx.message.channel.is_private:
         return
     embed = self._parse_pob(ctx.message.author, ctx.message.content)
     try:
         if embed:
             await ctx.message.channel.send(embed=embed)
     except discord.Forbidden:
         log.info("Tried pasting in channel without access.")
Beispiel #7
0
 def append_stat(self, key, val, stat_owner):
     # remove "Stat" from the string
     stat_owner = StatOwner.from_string(stat_owner)
     if not stat_owner in self.stats:
         self.stats[stat_owner] = {}
     try:
         self.stats[stat_owner][key] = float(val)
     except ValueError:
         log.info(f"Unable to convert '{val}' to float.")
Beispiel #8
0
 async def pob(self, ctx, *, key):
     if not self.allow_pming and ctx.message.channel.is_private:
         return
     xml, web_poe_token, paste_key = self._fetch_xml(
         ctx.message.author, ctx.message.content)
     if xml and web_poe_token:
         embed = self._generate_embed(web_poe_token, xml,
                                      ctx.message.author, paste_key)
         try:
             if embed:
                 await ctx.message.channel.send(embed=embed)
         except discord.Forbidden:
             log.info("Tried pasting in channel without access.")
def load_xml_by_pastebin_key(pastebin_url) -> ET:
    key = pastebin_url.split("/")[-1]
    xml_keys = get_pastebin_keys()

    if key not in xml_keys:
        log.warning(f"Downloading xml from pastebin for key={key}")
        PastebinHelper.fetch_pastebin(key)

    matches = [file for file in get_pastebin_file_dir_files() if key in file]
    build_xml_file = matches[0] if len(matches) > 0 else None
    path_to_build_xml = get_pastebin_file(build_xml_file)
    with open(path_to_build_xml, "r") as f:
        demo_author = None
        log.info(f"Testing whether we can parse '{build_xml_file}'")

        xml_tree = ET.fromstring(f.read())
    return xml_tree
def parse_build(xml_root) -> Build:
    """
    Completely parse the given pob xml into a build.
    :param xml_root: root node of pob xml
    :return: completely parsed build
    """
    xml_build = xml_root.find('Build')
    xml_items = xml_root.find('Items')
    xml_skills = xml_root.find('Skills')
    xml_tree = xml_root.find('Tree')
    selected_tree = _get_tree_link(xml_tree)

    # parse items
    item_slots = _parse_item_slots(xml_items)
    skills = _parse_skills(xml_skills)
    active_skill = get_attrib_if_exists(xml_build, 'mainSocketGroup')

    build = Build(xml_build.attrib['level'], xml_build.attrib['targetVersion'],
                  get_attrib_if_exists(xml_build, 'bandit'),
                  xml_build.attrib['className'],
                  xml_build.attrib['ascendClassName'], selected_tree, skills,
                  active_skill, item_slots)
    for player_stat in xml_build:
        if 'stat' in player_stat.attrib and 'value' in player_stat.attrib:
            build.append_stat(player_stat.attrib['stat'],
                              player_stat.attrib['value'], player_stat.tag)
        else:
            log.info(
                f"Encountered unsupported player stat: k={player_stat.tag}, v={player_stat.attrib}"
            )

    # parse config
    config = xml_root.find('Config')
    if not config == None:
        for input in xml_root.find('Config'):
            if input.tag == "Input":
                extracted = [val for (key, val) in input.attrib.items()]
                if len(extracted) < 1:
                    continue
                build.append_conf(extracted[0], extracted[1])

    # keystones
    tree = poe_tree_codec.codec.decode_url(selected_tree)
    build.keystones = tree.get_keystones(poe_tree_codec.codec.keystones)
    return build
Beispiel #11
0
async def on_ready():
    bot.add_cog(PoBCog(bot, config.active_channels, config.allow_pming))
    log.info(f'Logged in: uname={bot.user.name}, id={bot.user.id}')
    if config.presence_message:
        await bot.change_presence(activity=discord.Activity(name=config.presence_message))
Beispiel #12
0
from instance import config

from poediscordbot.discord_bot import bot
from poediscordbot.util.logging import log

if __name__ == '__main__':

    token = config.token  # create config.py file and enter a new string!
    if token:
        # initialize_logging()

        log.info("Starting pob discord bot...")
        bot.run(token)
    else:
        log.warning(
            "Missing token from config file. Please generate a bot and the token as described: "
            "https://www.writebots.com/discord-bot-token/")