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.")
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]
async def list_relics(client, message): relic_info = utils.get_json('relic_info') relics = list(relic_info.keys()) await client.send_message( message.channel, "WARNING: NOT MANTAINED, LIST OUT OF DATE.\n" +\ "Currently droppable relics:\n" + '\n'.join(relics))
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))
async def list_wanted(client, message): logger.info("list_wanted command.") raw_args = shlex.split(message.content)[1:] parser = utils.DiscordParser( '!listwanted', description="List parts wanted by users. Default sorting is by part.") parser.add_argument('-t', action='store_true', help="Sort by date posted.") parser.add_argument('-u', action='store_true', help="Sort by user.") parser.add_argument('-i', action='store_true', help="Sort by item.") args = await parser.parse_args(client, message.channel, raw_args) wanted_list = utils.get_json('wanted_list') if args.t: sort_func = lambda x: 0 # Keep order. elif args.u: sort_func = lambda x: x['user'] elif args.i: sort_func = lambda x: x['item_id'] else: # Default: Sort by user. sort_func = lambda x: x['user'] wanted_list.sort(key=sort_func) table = [['Part', 'User', 'Drop Loaction']] # Convert to table form. table_rows = list( map( lambda w: [ w['user'], w['item_id'], ', '.join(w['drop_list']) if isinstance(w['drop_list'], list) else '' ], wanted_list)) table.extend(table_rows) await utils.print_table(client, message, table, 'Wanted list:')
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)
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 + '".')