Skip to content

Commit

Permalink
Merge pull request #9 from offish/v2.0.5
Browse files Browse the repository at this point in the history
fix circular import and add more stuff
  • Loading branch information
offish authored Oct 21, 2023
2 parents 8ba411d + 1ae0441 commit bac2fcd
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 65 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ Tools and utilities for TF2 trading. Use 3rd party inventory providers, get SKUs
* Uses [tf2-sku](https://github.com/offish/tf2-sku)
* Uses [tf2-data](https://github.com/offish/tf2-data)
* Get SKUs directly from inventories/offers
* Convert name to SKU and vice versa
* Fetch inventories using 3rd party providers (avoid being rate-limited)
* Listen for Backpack.TF websocket events
* Listen for Prices.TF websocket events
* Interact with Prices.TF's API
* Get item properties (`is_craft_hat`, `get_paint`, `get_effect` etc.)
* Fetch TF2 Schema data
* Convert SKU/defindex to item image URL
* Convert name to SKU
* Calculate scrap and refined prices

## Setup
Expand Down
12 changes: 6 additions & 6 deletions src/tf2_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
__title__ = "tf2-utils"
__author__ = "offish"
__version__ = "2.0.3"
__version__ = "2.0.5"
__license__ = "MIT"

from .schema import SchemaItems, IEconItems
from .inventory import Inventory, map_inventory
from .sku import get_sku, get_sku_properties
from .sku import get_sku, get_sku_properties, sku_to_defindex
from .item import Item
from .offer import Offer
from .utils import to_refined, to_scrap, refinedify, account_id_to_steam_id
from .schema import SchemaItemsUtils
from .sockets import BackpackTFSocket, PricesTFSocket
from .prices_tf import PricesTF
from .item import Item
from .offer import Offer
from .inventory import Inventory, map_inventory
114 changes: 56 additions & 58 deletions src/tf2_utils/schema.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,50 @@
import time
from .sku import sku_to_defindex

from tf2_data import SchemaItems
from tf2_sku import to_sku
import requests


class SchemaItems(SchemaItems):
class SchemaItemsUtils(SchemaItems):
def __init__(
self, schema_items: str | list[dict] = "", defindex_names: str | dict = ""
) -> None:
super().__init__(schema_items, defindex_names)

def defindex_to_image_url(self, defindex: int, large: bool = False) -> str:
if isinstance(defindex, str):
defindex = int(defindex)
def defindex_to_name(self, defindex: int) -> str:
return self.defindex_names.get(defindex, "")

def name_to_defindex(self, name: str) -> int:
if name == "Random Craft Weapon":
return -50

if name == "Random Craft Hat":
return -100

defindexes = self.defindex_names.get(name, [])

if not defindexes:
return -1

has_multiple_defindexes = len(defindexes) != 1

if not has_multiple_defindexes:
return defindexes[0]

last_index = len(defindexes) - 1

# could be first or last defindex
match name:
case "Mann Co. Supply Crate Key":
return defindexes[0]

case "Name Tag":
return defindexes[last_index]

case _:
# use first defindex as default
return defindexes[0]

def defindex_to_image_url(self, defindex: int, large: bool = False) -> str:
# random craft weapon => shotgun
if defindex == -50:
defindex = 9
Expand All @@ -32,7 +62,7 @@ def defindex_to_image_url(self, defindex: int, large: bool = False) -> str:
return ""

def sku_to_image_url(self, sku: str, large: bool = False) -> str:
defindex = sku.split(";")[:-1][0]
defindex = sku_to_defindex(sku)
return self.defindex_to_image_url(defindex, large)

def name_to_sku(self, name: str) -> str:
Expand All @@ -57,10 +87,25 @@ def name_to_sku(self, name: str) -> str:
case "Strange":
quality = 11

case "Haunted":
quality = 13

case "Collector's":
quality = 14

defindex_name = name

while True:
defindex = self.defindex_names.get(defindex_name, -1)
# try whole name, then remove everything till the
# first space for each iteration if defindex
# for that name doesnt exist

# example:
# Uncraftable Strange Team Captain => -1
# Strange Team Captain => -1
# Team Captain => 378 != -1, so break

defindex = self.name_to_defindex(defindex_name)

if defindex != -1:
break
Expand All @@ -80,53 +125,6 @@ def name_to_sku(self, name: str) -> str:

return to_sku(sku_properties)


class IEconItems:
API_URL = "https://api.steampowered.com/IEconItems_440"
SCHEMA_OVERVIEW = API_URL + "/GetSchemaOverview/v0001"
PLAYER_ITEMS = API_URL + "/GetPlayerItems/v0001"
SCHEMA_ITEMS = API_URL + "/GetSchemaItems/v1"
STORE_DATA = API_URL + "/GetStoreMetaData/v1"
SCHEMA_URL = API_URL + "/GetSchemaURL/v1"

def __init__(self, api_key: str) -> None:
self.api_key = api_key

def __get(self, url: str, params: dict = {}) -> dict:
params["key"] = self.api_key

res = requests.get(url, params=params)

try:
return res.json()
except:
return {}

def get_player_items(self, steamid: str) -> dict:
return self.__get(self.PLAYER_ITEMS, {"steamid": steamid})

def get_schema_items(self, start: int = 0, language: str = "en") -> dict:
return self.__get(
self.SCHEMA_ITEMS, {"language": language.lower(), "start": start}
)

def get_all_schema_items(self, language: str = "en", sleep: float = 5.0) -> list:
items = []
start = 0

while start is not None:
response = self.get_schema_items(start, language=language)["result"]
items += response.get("items", [])
start = response.get("next") # None if not found
time.sleep(sleep)

return items

def get_schema_overview(self, language: str = "en") -> dict:
return self.__get(self.SCHEMA_OVERVIEW, {"language": language.lower()})

def get_schema_url(self) -> dict:
return self.__get(self.SCHEMA_URL, {})

def get_store_meta_data(self, language: str = "en") -> dict:
return self.__get(self.STORE_DATA, {"language": language.lower()})
def sku_to_name(self, sku: str) -> str:
defindex = sku_to_defindex(sku)
return self.defindex_to_name(defindex)
4 changes: 4 additions & 0 deletions src/tf2_utils/sku.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def get_sku_properties(item: Item | dict) -> dict:
return sku_properties


def sku_to_defindex(sku: str) -> int:
return int(sku.split(";")[:-1][0])


def get_sku(item: Item | dict) -> str:
if isinstance(item, dict):
item = Item(item)
Expand Down
70 changes: 70 additions & 0 deletions tests/test_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from src.tf2_utils import SchemaItemsUtils

from unittest import TestCase


schema_items = SchemaItemsUtils() # uses local files by default


class TestUtils(TestCase):
def test_map_defindex_names(self):
response = schema_items.map_defindex_name()
self.assertNotEqual({}, response)

def test_name_to_sku_tod(self):
sku = schema_items.name_to_sku("Uncraftable Tour of Duty Ticket")
self.assertEqual("725;6;uncraftable", sku)

def test_name_to_sku_key(self):
sku = schema_items.name_to_sku("Mann Co. Supply Crate Key")
self.assertEqual("5021;6", sku)

def test_name_to_sku_name_tag(self):
sku = schema_items.name_to_sku("Name Tag")
self.assertEqual("5020;6", sku)

def test_name_to_sku_pure(self):
ref = schema_items.name_to_sku("Refined Metal")
rec = schema_items.name_to_sku("Reclaimed Metal")
scrap = schema_items.name_to_sku("Scrap Metal")

self.assertEqual("5002;6", ref)
self.assertEqual("5001;6", rec)
self.assertEqual("5000;6", scrap)

def test_name_to_sku_non_existing(self):
# this item does not exist
item_name = "Non-Craftable Strange Team Captain"
sku = schema_items.name_to_sku(item_name)
defindex = schema_items.name_to_defindex(item_name)

self.assertEqual("378;11;uncraftable", sku)
self.assertEqual(-1, defindex)

def test_name_to_sku_qualities(self):
unique = schema_items.name_to_sku("Team Captain")
genuine = schema_items.name_to_sku("Genuine Team Captain")
haunted = schema_items.name_to_sku("Haunted Team Captain")
strange = schema_items.name_to_sku("Strange Team Captain")
vintage = schema_items.name_to_sku("Vintage Team Captain")
collectors = schema_items.name_to_sku("Collector's Team Captain")

self.assertEqual("378;1", genuine)
self.assertEqual("378;3", vintage)
self.assertEqual("378;6", unique)
self.assertEqual("378;11", strange)
self.assertEqual("378;13", haunted)
self.assertEqual("378;14", collectors)

def test_sku_to_name_tod(self):
name = schema_items.sku_to_name("725;6;uncraftable")
self.assertEqual("Tour of Duty Ticket", name)

def test_sku_to_name_key(self):
name = schema_items.sku_to_name("5021;6")
self.assertEqual("Mann Co. Supply Crate Key", name)

def test_image_equal(self):
ellis_cap = schema_items.defindex_to_image_url(263)
random_craft_hat = schema_items.sku_to_image_url("-100;6")
self.assertEqual(ellis_cap, random_craft_hat)

0 comments on commit bac2fcd

Please sign in to comment.