def warehouse_data(update, context): '''See and clear warehouse_data''' text = str(warehouse_load_saved()) if context.args and context.args[0] == 'clear': os.remove('warehouse.dict') logging.info(f'bot said:\n{text}') send(text, update, context)
def stock_list(context): warehouse = warehouse_load_saved(guild=context.user_data.get('guild', '')) hours = 1.5 responses = [] now = datetime.datetime.utcnow() if (res := warehouse.get('res', {})) and ( age := now - res['timestamp']) < datetime.timedelta(hours=hours): output = [ f'Based on /g_stock_res data {age.seconds // 60} minutes old:\n⚖️' ] for x in range(1, 39): if f'{x:02}' in id_lookup: res['data'][f'{x:02}'] = res['data'].get(f'{x:02}', 0) for id in sorted(res['data'], key=res['data'].get, reverse=True): trade = '✅' if id_lookup[id]['Exchange'] else '❌' output.append( f'{trade}<code>{id}</code> {titlecase(id_lookup[id]["Name"])} x {res["data"][id]}' ) sort_by_weight = { id: res['data'][id] * id_lookup[id]['Weight'] for id in res['data'] } sort_by_weight = sorted(sort_by_weight, key=sort_by_weight.get, reverse=True) x = [[res['data'][id] for id in sort_by_weight], [ res['data'][id] * (id_lookup[id]['Weight'] - 1) if id_lookup[id]['Weight'] == 2 else 0 for id in sort_by_weight ], [ res['data'][id] * (id_lookup[id]['Weight'] - 1) if id_lookup[id]['Weight'] >= 3 else 0 for id in sort_by_weight ]] r = range(len(sort_by_weight)) plt.clf() # clear plot, because it doesn't get cleared from last run plt.barh(r, x[0]) plt.barh(r, x[1], left=x[0], color=(1, .6, 0)) # some color between yellow and orange plt.barh(r, x[2], left=x[0], color='red') plt.yticks(r, [f'{id_lookup[id]["Name"]} {id}' for id in sort_by_weight], fontsize='8') plt.legend(loc='upper right', labels=['Count', 'Double Weight', 'Triple Weight']) plt.subplots_adjust(left=0.3) buf = io.BytesIO() #buf.name = 'weight.png' plt.savefig(buf, format='png') buf.seek(0) responses.append(buf) responses.append('\n'.join(output))
def warehouse_in(): followup = { 'res': '/stock', 'alch': '/alch', 'rec': '/warehouse', 'parts': '/w 1' } guild = context.user_data.get('guild', '') if not hasattr(update.message.forward_from, 'id') or update.message.forward_from.id not in [ 408101137 ]: # @chtwrsbot ret.append('Must be a forward from @chtwrsbot. Try again.') else: now = update.message.forward_date warehouse = warehouse_load_saved(True) data = {} for row in text.split('\n')[1:]: s = row.split() data[s[0]] = int(s[-1]) id_sample = list(data.keys())[0] if id_sample[0].isdigit(): if int(id_sample) <= 38: key = 'res' else: key = 'alch' elif id_sample[0] in 'sp': key = 'misc' elif id_sample[0] == 'r': key = 'rec' elif id_sample[0] == 'k': key = 'parts' elif id_sample[0] in 'wuea': key = 'other' if not warehouse.get(guild): warehouse[guild] = {} if not warehouse[guild].get( key) or now > warehouse[guild][key].get( 'timestamp', datetime.datetime.min): warehouse[guild][key] = {'timestamp': now, 'data': data} with open('warehouse.dict', 'wb') as warehouseFile: pickle.dump(warehouse, warehouseFile) ret.append(followup.get(key, key)) else: ret.append(f'{key}, but not newer than data on file') if not guild: ret.append( "Your guild affiliation is not on file with this bot. Consider forwarding something that indicates what guild you're in. Eg: /me or /report or /hero" )
def alch_list(context): warehouse = warehouse_load_saved(guild=context.user_data.get('guild', '')) hours = 1.5 responses = [] now = datetime.datetime.utcnow() if (alch := warehouse.get('alch', {})) and ( age := now - alch['timestamp']) < datetime.timedelta(hours=hours): output = [ f'Based on /g_stock_alch data {age.seconds // 60} minutes old:\n' ] for id in sorted(alch['data'], key=alch['data'].get, reverse=True): output.append( f'<code>{id}</code> {titlecase(id_lookup[id]["Name"])} x {alch["data"][id]}' ) responses.append('\n'.join(output))
def withdraw_parts(matches): '''builds withdraw commands. expects an iterator of dicts with one key named "number" and the other named "id" or "name"''' warehouse = warehouse_load_saved( guild=context.user_data.get('guild', '')) hours = 1.5 now = datetime.datetime.utcnow() notice = '' command_suffixes = set() matches = list(matches) for match in matches: if match.get('name'): match['id'] = name_lookup[ match['name'].strip().lower()]['ItemID'] if match['id'][0].isdigit(): if int(match['id']) <= 38: command_suffixes.add('res') else: command_suffixes.add('alch') elif match['id'][0] in 'sp': command_suffixes.add('misc') elif match['id'][0] == 'r': command_suffixes.add('rec') elif match['id'][0] == 'k': command_suffixes.add('parts') elif match['id'][0] in 'wuea': command_suffixes.add('other') print(command_suffixes) guild_stock = {} for suffix in command_suffixes: pass if False and (res := warehouse.get( 'res', {})) and (age := now - res['timestamp']) < datetime.timedelta(hours=hours): pass
def warehouse_crafting(context): warehouse = warehouse_load_saved(guild=context.user_data.get('guild', '')) hours = 1.5 responses = [] now = datetime.datetime.utcnow() if (rec := warehouse.get('rec', {})) and (parts := warehouse.get('parts', {})) and \ (age_rec := now - rec['timestamp']) < datetime.timedelta(hours=hours) and \ (age_parts := now - parts['timestamp']) < datetime.timedelta(hours=hours): older_command = '/g_stock_parts' if age_parts >= age_rec else '/g_stock_rec' output = [ f'Based on {older_command} data {max(age_rec, age_parts).seconds // 60} minutes old:\n' ] page_counter = 0 for n in range(1, 103): if 1 <= n <= 18 or 59 <= n <= 61: parts_needed = 3 elif 100 <= n <= 102: parts_needed = 4 elif 19 <= n <= 58 or n in (91, 96, 97): parts_needed = 5 elif 78 <= n <= 90 or 92 <= n <= 95 or n in (98, 99): parts_needed = 6 elif 62 <= n <= 77: parts_needed = 0 id = f'{n:02}' count_recipies = rec['data'].get(f'r{id}', 0) count_parts = parts['data'].get(f'k{id}', 0) if count_recipies or count_parts: complete_parts_sets = count_parts // parts_needed parts_missing_for_next_set = count_parts % parts_needed recipies_missing = complete_parts_sets - count_recipies things_missing = int(not bool(count_recipies)) + max( parts_needed - count_parts, 0) num_craftable = min(count_recipies, complete_parts_sets) ready = '✅' if num_craftable else '❌' name = id_lookup["r" + id]['Name'].rpartition(" ")[0] finished_part_id = name_lookup[name]['ItemID'] part_name = titlecase(id_lookup["k" + id]['Name'].rpartition(" ")[2]) # Getting through this gauntlet without hitting a continue means you get displayed if not num_craftable and not context.args: continue if context.args and context.args[0].lower() != 'all': if context.args[0].lower() in name: pass elif context.args[0].isdigit( ) and 0 < things_missing <= int(context.args[0]): pass elif context.args[0].lower().startswith('overstock'): try: multiple = int(context.args[1]) except IndexError: multiple = 2 if count_parts / parts_needed <= multiple and count_recipies <= multiple: continue else: continue output.append( f'{ready} {id} {titlecase(name)} <code>{finished_part_id}</code>' ) if num_craftable: output.append(f'<code> {num_craftable}</code> Can be made') output.append( f'<code>{parts_needed} {part_name}s per recipe</code>') output.append( f'<code> {count_recipies} Recipe{"s" if count_recipies != 1 else ""}</code>' ) output.append( f'<code> {count_parts} {part_name}{"s" if count_parts != 1 else ""}</code>' ) output.append(' ') page_counter += 1 if page_counter >= 20: responses.append('\n'.join(output)) page_counter = 0 output = [] result = '\n'.join(output) if result: responses.append(result) if result.rstrip().endswith(':'): responses.append('No matches in stock')