Example #1
0
    async def on_message(self, message):
        """
        Handle message events
        :param message: received
        :return: None
        """
        react_to_dms = isinstance(message.channel, discord.abc.PrivateChannel) and self.allow_pming

        if message.author.bot:
            return

        if 'help' in message.content.lower() and react_to_dms:
            await message.channel.send("Paste your pastebin here for a quick overview or use '!pob <pastebin>' for a "
                                       "detailed response.")
            return

        if (react_to_dms or message.channel.name in self.active_channels) \
                and not util.starts_with("!pob", message.content[:4]) \
                and "pastebin.com/" in message.content:
            # check if valid xml
            # send message
            log.debug(f"A| {message.channel}: {message.content}")
            try:
                embed = self._parse_pob(message.author, message.content, minify=True)
                if embed:
                    await message.channel.send(embed=embed)
            except HTTPError as err:
                log.error(f"Pastebin: Invalid pastebin-url msg={err}")
            except pastebin.CaptchaError as err:
                log.error(f"Pastebin: Marked as spam msg={err}")
                await message.channel.send(err.message)
Example #2
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
Example #3
0
    def fetch_config(path_to_pob_conf):
        """
        Read the current PoB master branch configoptions and create a json file for it.
        """
        url = f"{PobConfig.COMMUNITY_POB_RAW_GITHUB_URL}src/Modules/ConfigOptions.lua"
        url = request.urlopen(url)
        content = url.read().decode('utf-8')
        conditions = [line.strip() for line in content.split('{ var') if
                      "condition" in line.lower() or "ifflag" in line.lower()]
        keywords = ['var', 'label', 'ifOption', 'ifSkill', 'ifSkillList']
        regex = r'(\w+)\s*=\s*((?:"[^"]+")|{(?:\s*"[^"]+",?\s*)+})'

        attributes = {}
        for condition in conditions:
            attribute = {}
            condition = "var " + re.sub(r'{ label(.|\s)+$', '', condition)
            matches = re.findall(regex, condition)

            for m in matches:
                key = m[0].strip()
                val = m[1].strip()

                if val.startswith('"'):
                    val = val.replace('"', '')
                elif val.startswith('{'):
                    val = list(
                        map(lambda v: v.replace('"', '').replace('{', '').replace('}', '').strip(), val.split(',')))

                if key not in attribute and key in keywords:
                    attribute[key] = val

            if any(key in keywords for key in attribute):
                attributes[attribute['var']] = attribute

        pob_config_content = {'utc-date': datetime.utcnow().isoformat(), 'conf': attributes}
        try:
            with open(path_to_pob_conf, 'r') as file:
                file_content = json.load(file)
                if 'conf' in file_content:
                    # we need to do this to keep manually entered values in our file such as category
                    for confkey in file_content['conf']:
                        print(f">> {file_content['conf'][confkey]}")
                        if confkey in attributes:
                            file_content['conf'][confkey].update(attributes[confkey])
                        else:
                            log.error(f"Skipped config key: Please inform the bot author that the key '{confkey}' "
                                      f"could not be parsed.")

                    new_keys = [key for key in attributes if not any(k == key for k in file_content['conf'])]
                    print(new_keys)
                    for key in new_keys:
                        file_content['conf'][key] = attributes[key]

                    pob_config_content = {'utc-date': datetime.utcnow().isoformat(), 'conf': file_content['conf']}
        except FileNotFoundError:
            pass

        with open(path_to_pob_conf, 'w') as file:
            json.dump(pob_config_content, file, indent=4)
Example #4
0
def decode_base64_and_inflate(b64string):
    try:
        decoded_data = base64.b64decode(b64string)
        return zlib.decompress(decoded_data)
    except zlib.error as err:
        log.error(f"ZLib Error in paste: err={err}. Data={b64string}")
    except ValueError as err:
        log.error(f"Value Error in paste: err={err}")
Example #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))
Example #6
0
 def _generate_embed(web_poe_token, xml, author, paste_key, minify=False):
     if xml:
         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}"
             )
Example #7
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}")
Example #8
0
    def _fetch_xml(author, content):
        """
        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_key = PoBCog._detect_paste_key(content, author)
        if paste_key:
            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)
            return xml, web_poe_token, paste_key
        else:
            log.error(f"No Paste key found")
            return
Example #9
0
def urllib_error_retry(attempt_number, ms_since_first_attempt):
    delay = 1 * (2**(attempt_number - 1))
    log.error(
        f"An error occurred during get_url_data(). Sleeping for {delay:.0f}s before retrying..."
    )
    return delay * 1000