|
1 | 1 | import re |
2 | 2 | import time |
3 | 3 | import traceback |
4 | | -from tkinter import TclError |
5 | | -from tkinter import Tk |
6 | | -from typing import Dict |
7 | | -from typing import List |
| 4 | +from itertools import chain |
| 5 | +from tkinter import TclError, Tk |
| 6 | +from typing import Any, Collection, Dict, Iterable, List, Optional, Tuple |
8 | 7 |
|
9 | 8 | import requests |
10 | | -from colorama import Fore |
11 | | -from colorama import deinit |
12 | | -from colorama import init |
| 9 | +from colorama import Fore, deinit, init |
13 | 10 |
|
14 | 11 | # Local imports |
15 | | -from utils.config import LEAGUE |
16 | | -from utils.config import PROJECT_URL |
17 | | -from utils.config import USE_GUI |
18 | | -from utils.config import USE_HOTKEYS |
19 | | -from utils.currency import CATALYSTS |
20 | | -from utils.currency import CURRENCY |
21 | | -from utils.currency import DIV_CARDS |
22 | | -from utils.currency import ESSENCES |
23 | | -from utils.currency import FOSSILS |
24 | | -from utils.currency import FRAGMENTS_AND_SETS |
25 | | -from utils.currency import INCUBATORS |
26 | | -from utils.currency import OILS |
27 | | -from utils.currency import RESONATORS |
28 | | -from utils.currency import SCARABS |
29 | | -from utils.currency import VIALS |
| 12 | +from enums.item_modifier_type import ItemModifierType |
| 13 | +from models.item_modifier import ItemModifier |
| 14 | +from utils.config import LEAGUE, PROJECT_URL, USE_GUI, USE_HOTKEYS |
| 15 | +from utils.currency import ( |
| 16 | + CATALYSTS, |
| 17 | + CURRENCY, |
| 18 | + DIV_CARDS, |
| 19 | + ESSENCES, |
| 20 | + FOSSILS, |
| 21 | + FRAGMENTS_AND_SETS, |
| 22 | + INCUBATORS, |
| 23 | + OILS, |
| 24 | + RESONATORS, |
| 25 | + SCARABS, |
| 26 | + VIALS, |
| 27 | +) |
30 | 28 | from utils.exceptions import InvalidAPIResponseException |
31 | | -from utils.trade import get_leagues |
| 29 | +from utils.trade import get_item_modifiers, get_leagues |
32 | 30 |
|
33 | 31 | DEBUG = False |
34 | 32 |
|
35 | | - |
36 | | -# All available stats on items. |
37 | | -ITEM_MODIFIERS = requests.get(url="https://www.pathofexile.com/api/trade/data/stats").json() |
| 33 | +ITEM_MODIFIERS: Optional[Tuple[ItemModifier, ...]] = None |
38 | 34 |
|
39 | 35 |
|
40 | 36 | def parse_item_info(text: str) -> Dict: |
@@ -422,7 +418,11 @@ def query_trade( |
422 | 418 | j["query"]["stats"][0]["type"] = "and" |
423 | 419 | j["query"]["stats"][0]["filters"] = [] |
424 | 420 | for stat in stats: |
425 | | - (proper_affix, value) = find_affix_match(stat) |
| 421 | + try: |
| 422 | + (proper_affix, value) = find_affix_match(stat) |
| 423 | + except NotImplementedError: |
| 424 | + # Can't find mod, move on |
| 425 | + continue |
426 | 426 | affix_types = ["implicit", "crafted", "explicit", "enchantments"] |
427 | 427 | if any(atype in proper_affix for atype in affix_types): # If proper_affix is an actual mod... |
428 | 428 | j["query"]["stats"][0]["filters"].append({"id": proper_affix, "value": {"min": value, "max": 999}}) |
@@ -457,7 +457,7 @@ def query_trade( |
457 | 457 | print( |
458 | 458 | "[-] Removing the" |
459 | 459 | + Fore.CYAN |
460 | | - + f" {stat_translate(i)} " |
| 460 | + + f" {stat_translate(i['id']).text} " |
461 | 461 | + Fore.WHITE |
462 | 462 | + "mod from the list due to" |
463 | 463 | + Fore.RED |
@@ -485,7 +485,7 @@ def query_trade( |
485 | 485 | print( |
486 | 486 | "[-] Removing the" |
487 | 487 | + Fore.CYAN |
488 | | - + f" {stat_translate(i)} " |
| 488 | + + f" {stat_translate(i['id']).text} " |
489 | 489 | + Fore.WHITE |
490 | 490 | + "mod from the list due to" |
491 | 491 | + Fore.RED |
@@ -684,7 +684,7 @@ def result_prices_are_none(j: Dict) -> bool: |
684 | 684 | return all(x["listing"]["price"] == None for x in j) |
685 | 685 |
|
686 | 686 |
|
687 | | -def query_exchange(qcur, league): |
| 687 | +def query_exchange(qcur): |
688 | 688 | """ |
689 | 689 | Build JSON for fetch request of wanted currency exchange. |
690 | 690 | """ |
@@ -728,7 +728,7 @@ def query_exchange(qcur, league): |
728 | 728 | return results |
729 | 729 |
|
730 | 730 |
|
731 | | -def affix_equals(text, affix): |
| 731 | +def affix_equals(text, affix) -> Optional[int]: |
732 | 732 | """ |
733 | 733 | Clean up the affix to match the given text so we can find the correct id to search with. |
734 | 734 |
|
@@ -758,94 +758,52 @@ def affix_equals(text, affix): |
758 | 758 | print( |
759 | 759 | "[+] Found mod " + Fore.GREEN + f"{text[0:]}: {value}" |
760 | 760 | ) # TODO: support "# to # damage to attacks" type mods and other similar |
761 | | - return (True, value) |
| 761 | + return value |
762 | 762 |
|
763 | | - return (False, 0) |
| 763 | + return None |
764 | 764 |
|
765 | 765 |
|
766 | | -def find_affix_match(affix): |
| 766 | +def find_affix_match(affix: str) -> Tuple[str, int]: |
767 | 767 | """ |
768 | 768 | Search for the proper id to return the correct results. |
769 | 769 |
|
770 | 770 | returns tuple (id of the affix requested, value) |
771 | 771 | """ |
772 | | - pseudos = ITEM_MODIFIERS["result"][0]["entries"] |
773 | | - explicits = ITEM_MODIFIERS["result"][1]["entries"] |
774 | | - implicits = ITEM_MODIFIERS["result"][2]["entries"] |
775 | | - crafted = ITEM_MODIFIERS["result"][5]["entries"] |
776 | | - enchantments = ITEM_MODIFIERS["result"][4]["entries"] |
777 | | - proper_affix = ("", 0) |
| 772 | + |
| 773 | + def get_mods_by_type(type: ItemModifierType) -> Iterable[ItemModifier]: |
| 774 | + return (x for x in ITEM_MODIFIERS if x.type == type) |
778 | 775 |
|
779 | 776 | if DEBUG: |
780 | 777 | print("AFFIX:", affix) |
781 | 778 |
|
782 | | - if "(pseudo)" in affix: |
783 | | - for pseudo in pseudos: |
784 | | - (match, value) = affix_equals(pseudo["text"], affix) |
785 | | - if match: |
786 | | - proper_affix = (pseudo["id"], value) |
787 | | - |
788 | | - elif "(implicit)" in affix: |
789 | | - for implicit in implicits: |
790 | | - (match, value) = affix_equals(implicit["text"], affix) |
791 | | - if match: |
792 | | - proper_affix = (implicit["id"], value) |
793 | | - |
794 | | - elif "(crafted)" in affix: |
795 | | - for craft in crafted: |
796 | | - (match, value) = affix_equals(craft["text"], affix) |
797 | | - if match: |
798 | | - proper_affix = (craft["id"], value) |
799 | | - |
| 779 | + if re.search(r"\((pseudo|implicit|crafted)\)", affix): |
| 780 | + # Do these need to be searched in a specific order? |
| 781 | + search_order = [ItemModifierType.PSEUDO, ItemModifierType.IMPLICIT, ItemModifierType.CRAFTED] |
| 782 | + search_mods = chain(*(get_mods_by_type(x) for x in search_order)) |
| 783 | + for mod in search_mods: |
| 784 | + value = affix_equals(mod.text, affix) |
| 785 | + if value is not None: |
| 786 | + return (mod.id, value) |
800 | 787 | else: |
801 | | - Found = False |
802 | | - for explicit in explicits: |
803 | | - (match, value) = affix_equals(explicit["text"], affix) |
804 | | - if match: |
805 | | - proper_affix = (explicit["id"], value) |
806 | | - Found = True |
| 788 | + for explicit in (x for x in ITEM_MODIFIERS if x.type is ItemModifierType.EXPLICIT): |
| 789 | + value = affix_equals(explicit.text, affix) |
| 790 | + if value is not None: |
| 791 | + return (explicit.id, value) |
807 | 792 |
|
808 | | - if not Found: |
809 | | - # Maybe it's an enchantment |
810 | | - for enchant in enchantments: |
811 | | - (match, value) = affix_equals(enchant["text"], affix) |
812 | | - if match: |
813 | | - proper_affix = (enchant["id"], value) |
| 793 | + # Maybe it's an enchantment |
| 794 | + for enchant in (x for x in ITEM_MODIFIERS if x.type is ItemModifierType.ENCHANT): |
| 795 | + value = affix_equals(enchant.text, affix) |
| 796 | + if value is not None: |
| 797 | + return (enchant.id, value) |
814 | 798 |
|
815 | | - return proper_affix |
| 799 | + raise NotImplementedError("Unable to find matching affix.") |
816 | 800 |
|
817 | 801 |
|
818 | | -def stat_translate(jaffix): |
| 802 | +def stat_translate(jaffix: str) -> ItemModifier: |
819 | 803 | """ |
820 | 804 | Translate id to the equivalent stat. |
821 | 805 | """ |
822 | | - affix = jaffix["id"] |
823 | | - |
824 | | - pseudos = ITEM_MODIFIERS["result"][0]["entries"] |
825 | | - explicits = ITEM_MODIFIERS["result"][1]["entries"] |
826 | | - implicits = ITEM_MODIFIERS["result"][2]["entries"] |
827 | | - crafted = ITEM_MODIFIERS["result"][5]["entries"] |
828 | | - enchantments = ITEM_MODIFIERS["result"][4]["entries"] |
829 | | - |
830 | | - # TODO add enchantments ability to be lookedup. |
831 | | - |
832 | | - if "pseudo" in affix: |
833 | | - return find_stat_by_id(affix, pseudos) |
834 | | - elif "implicit" in affix: |
835 | | - return find_stat_by_id(affix, implicits) |
836 | | - elif "crafted" in affix: |
837 | | - return find_stat_by_id(affix, crafted) |
838 | | - else: |
839 | | - return find_stat_by_id(affix, explicits) |
840 | | - |
841 | | - |
842 | | -def find_stat_by_id(affix, stat_list): |
843 | | - """ |
844 | | - Helper function to find stats by their id. |
845 | | - """ |
846 | | - for stat in stat_list: |
847 | | - if stat["id"] == affix: |
848 | | - return stat["text"] |
| 806 | + return next(x for x in ITEM_MODIFIERS if x.id == jaffix) |
849 | 807 |
|
850 | 808 |
|
851 | 809 | def watch_clipboard(): |
@@ -1067,14 +1025,17 @@ def watch_clipboard(): |
1067 | 1025 | root.withdraw() |
1068 | 1026 | DEBUG = False |
1069 | 1027 |
|
| 1028 | + ITEM_MODIFIERS = get_item_modifiers() |
| 1029 | + print(f"Loaded {len(ITEM_MODIFIERS)} item mods.") |
1070 | 1030 | valid_leagues = get_leagues() |
| 1031 | + |
| 1032 | + print(f"If you wish to change the selected league you may do so in settings.cfg.") |
| 1033 | + print(f"Valid league values are {Fore.MAGENTA}{', '.join(valid_leagues)}.") |
| 1034 | + |
1071 | 1035 | if LEAGUE not in valid_leagues: |
1072 | 1036 | print(f"Unable to locate {LEAGUE}, please check settings.cfg.") |
1073 | | - |
1074 | 1037 | else: |
1075 | 1038 | print(f"All values will be from the {Fore.MAGENTA}{LEAGUE} league") |
1076 | | - print(f"If you wish to change the selected league you may do so in settings.cfg.") |
1077 | | - print(f"Valid league values are {Fore.MAGENTA}{', '.join(valid_leagues)}.") |
1078 | 1039 |
|
1079 | 1040 | if USE_HOTKEYS: |
1080 | 1041 | import utils.hotkeys as hotkeys |
|
0 commit comments