Exemple #1
0
def part_to_relic_mapping(relic_info):
    """
    DEPRECIATED
    Converts the relic_info dictionary into a part-first dictionary.
    return: {
        'part': [
            '$relic_name $rarity'
        ]
    }
    """
    parts = {}

    for relic in relic_info:
        drops = relic_info[relic]['drops']

        for i in range(len(drops)):
            part = utils.to_itemid(drops[i])
            drop_rarity = '%s %s' % (relic, utils.idx_to_rarity(i))

            if part in parts:
                parts[part].append(drop_rarity)
            else:
                parts[part] = [drop_rarity]

    return parts
Exemple #2
0
async def add_wanted_part(client, message):
    raw_args = shlex.split(message.content)[1:]

    parser = utils.DiscordParser("!want")
    parser.add_argument('part', type=str, help="The wanted part name.")

    parser.add_argument('--unsafe',
                        action='store_true',
                        help="Do not check for item validity.")

    args = await parser.parse_args(client, message.channel, raw_args)

    item = args.part
    item_id = utils.to_itemid(item)

    user = message.author

    logger.info("item_id: %s, user: %s" % (item_id, user.name))

    market_url = utils.warframe_market_url(item_id)

    if not args.unsafe:
        res = await utils.async_request(market_url)

    if args.unsafe or res.ok:
        parts_info = utils.get_json('part_info')

        drop_relic_list = parts_info.get(item_id)

        new_item = {
            'item_id': item_id,
            'user': user.name,
            'userID': user.id,
            'drop_list': drop_relic_list
        }

        wanted_list = utils.get_json('wanted_list')
        wanted_list.append(new_item)
        utils.save_json('wanted_list', wanted_list)

        logger.info("Adding part.")

        out_message = 'Adding ' + item_id + ' to wanted list for ' +\
                      user.name + '.'

        await client.send_message(message.channel, out_message)
    else:
        logger.warning("Bad item name or uncached item %s" % item_id)
        await client.send_message(message.channel,
                                  "Bad item id or uncached item.")
Exemple #3
0
async def check_alerts(client, channel):
    logger.info("Checking for alerts.")
    wanted_list = utils.get_json('wanted_list')

    url = 'http://deathsnacks.com/wf/'
    req = await utils.async_request(url)

    if req.ok:
        ts = int(time.time())
        soup = BeautifulSoup(req.text, 'html.parser')

        parts = soup.find(
                'ul',
                {'class': ['list-group', 'alerts-container']})\
            .find_all('span', {'class': 'badge'})

        for soup_item in parts:
            item = soup_item.text
            if item.endswith(' Blueprint'):
                item = item[:-10]
            item_id = utils.to_itemid(item)

            users = []
            usernames = []
            for i in range(len(wanted_list)):
                want = wanted_list[i]
                if want['item_id'] == item_id:

                    if (('last_updated' not in want) or
                            # If within the same hour, probably the same alert.
                        (ts - want['last_updated'] >= 60 * 60)):

                        users.append(want['userID'])
                        usernames.append(want['user'])
                        wanted_list[i]['last_updated'] = ts

            if len(users) > 0:
                logger.info('Alert for %s, notifying %s' %
                            (item_id, ', '.join(usernames)))

                for userID in users:
                    user = await client.get_user_info(userID)
                    await client.send_message(
                        user, 'Alert for ' + item_id +
                        '\nhttp://deathsnacks.com/wf/')

        utils.save_json('wanted_list', wanted_list)
    else:
        logger.error("Request for %s returned error code %s." %
                     (url, req.status_code))
Exemple #4
0
async def get_relic_info(relic_name):
    """
    Gets relic information and caches it, if not already cached.
    Also helps mantain a parts list.
    """

    logger.info("Fetching relic info for %s." % relic_name)

    relic_infos = utils.get_json('relic_info')

    if relic_name in relic_infos:
        return relic_infos[relic_name]

    logger.info("Relic not in database. Searching Wikia.")

    relic_url = "https://warframe.fandom.com/wiki/%s" \
        % relic_name.replace(' ', '_')

    req = await utils.async_request(relic_url)
    if req.ok:
        soup = BeautifulSoup(req.text, 'html.parser')
    else:
        logger.error("Request to %s has response code %s."
                     % (relic_url, req.status_code))

        raise ValueError("Bad relic url.")


    relic_info = extract_relic_info(soup)

    # Cache.
    relic_infos[relic_name] = relic_info
    utils.save_json('relic_info', relic_infos)


    # Update parts mapping.
    part_info = utils.get_json('part_info')

    drops = relic_info['drops']

    for i in range(len(drops)):
        part = utils.to_itemid(drops[i])
        drop_rarity = '%s %s' % (relic, utils.idx_to_rarity(i))

        if part in part_info:
            part_info[part].append(drop_rarity)
        else:
            part_info[part] = [drop_rarity]
Exemple #5
0
async def remove_part(client, message):
    raw_args = shlex.split(message.content)[1:]

    parser = utils.DiscordParser("!remove")
    parser.add_argument('part', type=str, help='The part to remove.')

    args = await parser.parse_args(client, message.channel, raw_args)

    item = args.part
    item_id = utils.to_itemid(item)

    user = message.author

    logger.info("item_id: %s, user: %s" % (item_id, user.name))

    wanted_list = utils.get_json('wanted_list')
    for i in range(len(wanted_list)):
        want = wanted_list[i]
        if want['userID'] == user.id and want['item_id'] == item_id:
            del wanted_list[i]

            utils.save_json('wanted_list', wanted_list)

            out_message = "Removed entry for part " + item_id +\
                " for user " + user.name + "."

            logger.info("Part removed.")
            await client.send_message(message.channel, out_message)

            return

    # If nothing got deleted, then will end up here.
    logger.info("Could not find matching part for user.")
    out_message = "Could not find entry for part " + item_id +\
        " for user " + user.name + "."

    await client.send_message(message.channel, out_message)
Exemple #6
0
async def mod_info(client, message):
    raw_args = shlex.split(message.content)[1:]

    parser = utils.DiscordParser("!mod")
    parser.add_argument("mod", type=str, help="The requested mod.")

    args = await parser.parse_args(client, message.channel, raw_args)

    item_id = utils.to_itemid(args.mod)
    wikia_id = utils.to_wikiaid(item_id)

    url = 'http://warframe.wikia.com/wiki/' + wikia_id

    req = await utils.async_request(url)

    if req.ok:
        soup = BeautifulSoup(req.text, 'html.parser')
        image_url = soup.find('img', {'class': 'pi-image-thumbnail'})\
            .attrs['src']

        await client.send_message(message.channel, image_url)
    else:
        await client.send_message(message.channel,
                                  "Could not find mod %s." % item_id)
Exemple #7
0
async def parts_info(client, message):
    raw_args = shlex.split(message.content)[1:]

    parser = utils.DiscordParser("!part")
    parser.add_argument("part", type=str, help="The requsted part.")

    args = await parser.parse_args(client, message.channel, raw_args)

    item = args.part
    item_id = utils.to_itemid(item)

    part_info = utils.get_json('part_info')
    if item_id in part_info:
        logging.info("Found relic info for %s." % item_id)
        await client.send_message(
            message.channel, 'Item ' + item_id + ' is dropped by ' +
            ', '.join(part_info[item_id]) + '.')

    url = utils.warframe_market_url(item_id)
    req = await utils.async_request(url)

    if req.ok:
        data = json.loads(req.text)

        prices = list(map(lambda x: x['platinum'], data['payload']['orders']))
        median = sorted(prices)[len(prices) // 2]

        logging.info("Median price for %s is %s plat." % (item_id, median))

        await client.send_message(
            message.channel,
            "Market price for " + item_id + ": " + str(median) + ' plat.')
    else:
        logging.info("Could not find item in warframe.market.")
        await client.send_message(message.channel,
                                  'Bad item name "' + item + '".')
Exemple #8
0
async def prime_info(client, message):
    raw_args = shlex.split(message.content)[1:]

    parser = utils.DiscordParser(
        "!info", description="Info and drop locations for prime items.")
    parser.add_argument("item",
                        type=str,
                        help="The requested weapon/warframe.")

    args = await parser.parse_args(client, message.channel, raw_args)

    item_id = utils.to_itemid(args.item)
    if not item_id.endswith('_prime'):
        item_id += '_prime'

    wikia_id = utils.to_wikiaid(item_id)

    url = 'http://warframe.wikia.com/wiki/' + wikia_id

    req = await utils.async_request(url)

    if req.ok:
        # try:
        soup = BeautifulSoup(req.text, 'html.parser')

        # Disambiguation between warframes and weapons.

        # Table rows.
        drop_table = soup.find('b', string='Drop Locations')\
            .next.next.next

        warframe_table = drop_table.find('div', {
            'class': 'tabbertab',
            'title': 'PC'
        })

        if warframe_table:
            table = warframe_table
        else:
            table = drop_table

        if not warframe_table:
            man_table = soup.find('table', {'class': 'foundrytable'})
            mats_row = man_table.find_all('tr', recursive=False)[1]
            mats_soup = mats_row.find_all('td')[:5]

            mats_str = '\nRequired materials:\n'
            for mat_soup in mats_soup:
                if mat_soup.text.strip() == '':
                    break

                mat = mat_soup.find('a').attrs['title']
                mat_count = mat_soup.text.strip()

                mats_str += '\t%s: %s\n' % (mat, mat_count)

        trs = table.find_all('tr')

        message_str = 'Drop locations for %s:\n```\n' % item_id
        for tr in trs:
            td = tr.find_all('td')
            part = td[0].text.strip()

            drop_locations = \
                BeautifulSoup(
                    str(td[1]).replace('<br/>', '\n'),
                    'html.parser') \
                .text.strip().split('\n')

            message_str += part + '\n'

            for drop_loc in drop_locations:
                message_str += '\t' + drop_loc + '\n'

        if not warframe_table:
            message_str += mats_str

        message_str += '```'

        await client.send_message(message.channel, message_str)
    else:
        await client.send_message(message.channel,
                                  "Could not find prime item %s." % item_id)