def find_affixes( official_query: OfficialApiQuery, affix_type: str = "explicit", exclude_affixes: List[Mod] = [], use_added_filter_for_speed: bool = True, ) -> Set[Mod]: stat_filter = StatFilters(filters=[], type="not") if use_added_filter_for_speed: official_query.stat_filters.append(added_filters[affix_type]) official_query.stat_filters.append(stat_filter) found_mods: Set[Mod] = set() results = search_and_fetch_batched([official_query])[0] if not results and use_added_filter_for_speed: logging.warn( "For unique items you might need to set use_added_filter_for_speed=False" ) added_mod = True while results and added_mod: added_mod = False new_found_mods = set() for result in results: parsed_result = OfficialApiResult(result) for mod in parsed_result.__getattribute__(f"{affix_type}s"): if mod not in exclude_affixes: new_found_mods.add(mod) if found_mods & new_found_mods: logging.warning( f"found a mod that should be excluded: {found_mods & new_found_mods} (for jewelry, try setting quality_max=0)" ) added_mod = len(new_found_mods.difference(found_mods)) > 0 found_mods = found_mods | new_found_mods stat_filter.filters = list( simplify_stat_filter({ stat_filter for mod in found_mods for stat_filter in mod.to_query_stat_filters() })) logging.info( f"Affix Finder: Found {len(new_found_mods)} new mods, blocking {len(found_mods)} mods" ) results = search_and_fetch_batched([official_query])[0] return found_mods
async def search_and_fetch_and_price(mod): results_entry = { "mod_str": str(mod), "mod_json": json.dumps(mod.json()) } mod_stat_filters = StatFilters(filters=mod.to_query_stat_filters()) query = OfficialApiQuery( category=item_class_value, corrupted=False, indexed="1week", mirrored=False, rarity="nonunique", stat_filters=[mod_stat_filters], ).json() results = await search_and_fetch_async(query) print(results_entry["mod_str"]) for idx, result in enumerate(results): parsed_result = OfficialApiResult(result) results_entry[f"price_{idx:02}"] = estimate_price_in_chaos( parsed_result.price) global results_df results_df = results_df.append(results_entry, ignore_index=True) return results_entry
def create_item_query(option_idx, ilvl, passive_count_min=None, passive_count_max=None): return OfficialApiQuery( stat_filters=[ StatFilters(filters=[ StatFilter("enchant.stat_3948993189", option=option_idx), StatFilter( "enchant.stat_3086156145", min=passive_count_min, max=passive_count_max, ), ]), ], ilvl_min=ilvl, mirrored=False, corrupted=False, rarity="nonunique", )
from typing import List, Set from PoEQuery.official_api import search_and_fetch_batched from PoEQuery.official_api_query import OfficialApiQuery, StatFilter, StatFilters from PoEQuery.official_api_result import Mod, OfficialApiResult import logging from itertools import combinations added_filters = { "implicit": StatFilters(filters=[ StatFilter(id="pseudo.pseudo_number_of_implicit_mods", min=1) ]), "explicit": StatFilters( filters=[StatFilter(id="pseudo.pseudo_number_of_affix_mods", min=1)]), "fractured": StatFilters(), } def simplify_stat_filter(stat_filters: Set[StatFilter], threshold: float = 1.0) -> Set[StatFilter]: """ takes in a list of stat_filters and attempts to simplify them by merging contiguous stat filters """ while True: for stat_filter_1, stat_filter_2 in combinations(stat_filters, 2): if stat_filter_1.id == stat_filter_2.id: # Two types of collisions:
def bisect_count_two_mod(query: OfficialApiQuery) -> List[OfficialApiQuery]: """""" if len(query.stat_filters) == 1: assert (query.stat_filters[0].type == "count" and query.stat_filters[0].min == 2 and query.stat_filters[0].max == None), "bisect_count_two_mod expects a count filter" count_stat_filters = query.stat_filters[0] n_filters = len(count_stat_filters.filters) if n_filters > 2: logging.info(f"Bisecting {n_filters} mods") filters = sorted(count_stat_filters.filters, key=lambda x: json.dumps(x.json())) left_filters = filters[:n_filters // 2] right_filters = filters[n_filters // 2:] left_query_copy, right_query_copy = deepcopy(query), deepcopy( query) left_query_copy.stat_filters[0].filters = left_filters right_query_copy.stat_filters[0].filters = right_filters cross_query_copy = deepcopy(query) cross_query_copy.stat_filters.append( StatFilters(filters=deepcopy(left_filters), type="count", min=1)) cross_query_copy.stat_filters.append( StatFilters(filters=deepcopy(right_filters), type="count", min=1)) return [left_query_copy, cross_query_copy, right_query_copy] elif len(query.stat_filters) == 3: assert all([ stat_filter.type == "count" for stat_filter in query.stat_filters ]) assert [stat_filter.min for stat_filter in query.stat_filters] == [1, 2, 1] assert all( [stat_filter.max == None for stat_filter in query.stat_filters]) left_filters = query.stat_filters[0].filters right_filters = query.stat_filters[2].filters if len(right_filters) == len(left_filters) == 1: return [] elif len(right_filters) > len(left_filters): query.stat_filters[0], query.stat_filters[2] = ( query.stat_filters[2], query.stat_filters[0], ) split_filters = sorted(query.stat_filters[0].filters, key=lambda x: json.dumps(x.json())) left_split_filters = split_filters[:len(split_filters) // 2] right_split_filters = split_filters[len(split_filters) // 2:] left_query = deepcopy(query) right_query = deepcopy(query) left_query.stat_filters[0].filters = left_split_filters right_query.stat_filters[0].filters = right_split_filters return [left_query, right_query] else: raise ValueError("Not a valid bisect partition")
}, { "id": 49, "text": "+12% to Chaos Resistance" }, { "id": 50, "text": "1% chance to Dodge Attack Hits" }, ] mods = find_affixes( OfficialApiQuery( stat_filters=[ StatFilters(filters=[ StatFilter("enchant.stat_3948993189", option=18), StatFilter("enchant.stat_3086156145"), ]) ], mirrored=False, corrupted=False, rarity="nonunique", ), affix_type="explicit", ) query = OfficialApiQuery( stat_filters=[ StatFilters(filters=[ StatFilter("enchant.stat_3948993189", option=18), StatFilter("enchant.stat_3086156145"), ]),
from PoEQuery.official_api_query import StatFilter, StatFilters, OfficialApiQuery from PoEQuery.affix_finder import find_affixes triple_implicit_stat_filter = StatFilters( filters=[StatFilter(id="explicit.stat_2304729532")], type="not") item_classes = dict(BOW="weapon.bow", CLAW="weapon.claw", BASE_DAGGER="weapon.basedagger", RUNE_DAGGER="weapon.runedagger", ONE_HANDED_AXE="weapon.oneaxe", ONE_HANDED_MACE="weapon.onemace", ONE_HANDED_SWORD="weapon.onesword", SCEPTRE="weapon.sceptre", BASE_STAFF="weapon.basestaff", WARSTAFF="weapon.warstaff", TWO_HANDED_AXE="weapon.twoaxe", TWO_HANDED_MACE="weapon.twomace", TWO_HANDED_SWORD="weapon.twosword", WAND="weapon.wand", BODY_ARMOUR="armour.chest", BOOTS="armour.boots", GLOVES="armour.gloves", HELMET="armour.helmet", SHIELD="armour.shield", QUIVER="armour.quiver", AMULET="accessory.amulet", BELT="accessory.belt", RING="accessory.ring", BASE_JEWEL="jewel.base", ABYSS_JEWEL="jewel.abyss",
for type in t: t.set_description(desc=f"watchstone - {type}") mods = find_affixes( OfficialApiQuery(type=type, identified=True, rarity="nonunique"), affix_type="explicit", ) all_query = OfficialApiQuery( type=type, # identified=True, rarity="nonunique", # mirrored=False, # enchanted=False, # corrupted=False, indexed="2weeks", stat_filters=[ StatFilters( [ stat_filter for mod in mods for stat_filter in mod.to_query_stat_filters() ], type="count", min=1, ) ], ) # results = search_and_fetch_batched(queries) asyncio.run( fetch_query_with_query_dividers(all_query, [bisect_count_one_mod]))
"min": 25, "max": 30 }], }) mods = find_affixes( OfficialApiQuery(name="Forbidden Shako", type="Great Crown", identified=True), affix_type="explicit", exclude_affixes=[attr_mod], use_added_filter_for_speed=False, ) for mod in tqdm(mods): results_entry = {"mod_str": str(mod), "mod_json": json.dumps(mod.json())} mod_stat_filters = StatFilters(filters=mod.to_query_stat_filters()) fetch_ids, total, query = search_query( OfficialApiQuery( name="Forbidden Shako", type="Great Crown", identified=True, corrupted=False, enchanted=False, indexed="2week", stat_filters=[mod_stat_filters], ).json()) print(mod, total) results = fetch_results(fetch_ids) for idx, result in enumerate(results): parsed_result = OfficialApiResult(result)
StatFilters( filters=[ StatFilter( id="fractured.stat_1671376347", min=18.0, max=29.0, disabled=False, ), StatFilter( id="fractured.stat_1290399200", min=21.0, max=50.0, disabled=False, ), StatFilter( id="fractured.stat_1037193709", min=10.5, max=52.5, disabled=False, ), StatFilter( id="fractured.stat_821021828", min=4.0, max=5.0, disabled=False ), StatFilter( id="fractured.stat_2843100721", min=1.0, max=1.0, disabled=False ), StatFilter( id="fractured.stat_4220027924", min=6.0, max=35.0, disabled=False, ), StatFilter( id="fractured.stat_2517001139", min=11.0, max=35.0, disabled=False, ), StatFilter( id="fractured.stat_2923486259", min=5.0, max=10.0, disabled=False, ), StatFilter( id="fractured.stat_210067635", min=17.0, max=25.0, disabled=False, ), StatFilter( id="fractured.stat_829382474", min=1.0, max=1.0, disabled=False ), StatFilter( id="fractured.stat_789117908", min=40.0, max=49.0, disabled=False, ), StatFilter( id="fractured.stat_3261801346", min=8.0, max=32.0, disabled=False, ), StatFilter( id="fractured.stat_691932474", min=21.0, max=325.0, disabled=False, ), StatFilter( id="fractured.stat_1509134228", min=20.0, max=64.0, disabled=False, ), StatFilter( id="fractured.stat_3695891184", min=11.0, max=14.0, disabled=False, ), StatFilter( id="fractured.stat_3556824919", min=15.0, max=29.0, disabled=False, ), StatFilter( id="fractured.stat_709508406", min=2.0, max=48.0, disabled=False ), StatFilter( id="fractured.stat_3639275092", min=-18.0, max=-18.0, disabled=False, ), StatFilter( id="fractured.stat_3336890334", min=36.0, max=85.0, disabled=False, ), StatFilter( id="fractured.stat_1940865751", min=6.0, max=27.0, disabled=False, ), StatFilter( id="fractured.stat_1050105434", min=40.0, max=109.0, disabled=False, ), StatFilter( id="fractured.stat_328541901", min=8.0, max=37.0, disabled=False ), StatFilter( id="fractured.stat_795138349", min=20.0, max=30.0, disabled=False, ), StatFilter( id="fractured.stat_3372524247", min=12.0, max=29.0, disabled=False, ), StatFilter( id="fractured.stat_2375316951", min=10.0, max=29.0, disabled=False, ), StatFilter( id="fractured.stat_387439868", min=11.0, max=36.0, disabled=False, ), ], type="not", ),