diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..693458a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,22 @@ +dist: xenial +language: python +python: + - "3.5" + - "3.6" + - "3.7" + - "3.8-dev" + - "nightly" + +matrix: + allow_failures: + - python: "3.8-dev" + - python: "nightly" + +install: + - pip install pytest + +before_script: + - "python setup.py install" + +script: + - pytest tests/test_miscutils.py diff --git a/BackpackTF/__pycache__/account.cpython-37.pyc b/BackpackTF/__pycache__/account.cpython-37.pyc index e34a77a..b093ce0 100644 Binary files a/BackpackTF/__pycache__/account.cpython-37.pyc and b/BackpackTF/__pycache__/account.cpython-37.pyc differ diff --git a/BackpackTF/__pycache__/miscutils.cpython-37.pyc b/BackpackTF/__pycache__/miscutils.cpython-37.pyc index 34e9f92..44fec8b 100644 Binary files a/BackpackTF/__pycache__/miscutils.cpython-37.pyc and b/BackpackTF/__pycache__/miscutils.cpython-37.pyc differ diff --git a/BackpackTF/account.py b/BackpackTF/account.py index ab4d695..22a1f40 100644 --- a/BackpackTF/account.py +++ b/BackpackTF/account.py @@ -201,4 +201,42 @@ def search_Classifieds(self, intent="dual", page_size=10, fold=1, item_name="Sod "https://backpack.tf/api/classifieds/search/v1?" + encoded) jsondata = json.loads(r.text) - return jsondata \ No newline at end of file + return jsondata + + + # + # This function extracts the trade url. + # + # listingJSON - the JSON object from the search_listings under whatever the listing thing you use is. + # + def extract_trade_url(self, listingJSON, proxy=None): + from lxml import html + import requests + import urllib.parse + import json + + payload = { + "item": listingJSON['item']['name'], + "steamid": listingJSON['steamid'], + "quality": listingJSON['item']['quality'] + } + + encoded = urllib.parse.urlencode(payload) + + if proxy == None: + r = requests.get( + "https://backpack.tf/classifieds?" + encoded.replace("+", "%20")) + else: + r = requests.get( + "https://backpack.tf/classifieds?" + encoded.replace("+", "%20"), proxies=proxy) + + with open('test.html', 'w+', encoding='utf-8') as thing: + thing.write(r.text) + + tree = html.fromstring(r.text) + + try: + url = tree.xpath("//li[@id='listing-" + listingJSON['id'] + "']/div[@class='listing-item']/div")[0].get('data-listing_offers_url') + return url + except: + raise IndexError('List index out of range') \ No newline at end of file diff --git a/BackpackTF/miscutils.py b/BackpackTF/miscutils.py index edcdfd4..788d8a9 100644 --- a/BackpackTF/miscutils.py +++ b/BackpackTF/miscutils.py @@ -1,91 +1,162 @@ class MiscUtils: def __init__(self): - self.active = 1 + import requests + import json + + r = requests.get("https://backpack.tf/filters") + + obj = json.loads(r.text) + + particles = obj['particle'] + qualities = obj['quality'] + rarities = obj['rarity'] + paints = obj['paint'] + origins = obj['origin'] + wear_tiers = obj['wear_tiers'] + killstreakers = obj['killstreakers'] + sheens = obj['sheens'] + killstreak_tiers = obj['killstreak_tiers'] + strange_parts = obj['strange_parts'] + + self.particleObj = {} + self.qualitiesObj = {} + self.raritiesObj = {} + self.paintsObj = {} + self.originsObj = {} + self.wear_tiersObj = {} + self.killstreakers = {} + self.sheensObj = {} + self.killstreak_tiers = {} + self.strange_partsObj = {} + + for particle in particles: + self.particleObj[particle['name'].lower()] = int(particle['id']) + + for quality in qualities: + self.qualitiesObj[quality['name'].lower()] = int(quality['id']) + + for rarity in rarities: + self.raritiesObj[rarity['name'].lower()] = int(rarity['id']) + + for paint in paints: + self.paintsObj[paint['name'].lower()] = int(paint['id']) + + for particle in origins: + self.originsObj[particle['name'].lower()] = int(particle['id']) + + for particle in wear_tiers: + self.wear_tiersObj[wear_tiers[particle]['name'].lower()] = int(wear_tiers[particle]['id']) + + for particle in killstreakers: + self.killstreakers[particle['name'].lower()] = int(particle['id']) + + for particle in sheens: + self.sheensObj[particle['name'].lower()] = int(particle['id']) + + for particle in killstreak_tiers: + self.killstreak_tiers[particle['name'].lower()] = int(particle['id']) + + for particle in strange_parts: + self.strange_partsObj[particle['name'].lower()] = int(particle['id']) + # # Converts quality string to quality int # def quality_String_To_Int(self, string): - checkStr = string.lower() - - if checkStr == "normal": - return 0 - elif checkStr == "genuine": - return 1 - elif checkStr == "vintage": - return 3 - elif checkStr == "unusual": - return 5 - elif checkStr == "unique": - return 6 - elif checkStr == "community": - return 7 - elif checkStr == "developer": - return 8 - elif checkStr == "selfmade": - return 9 - elif checkStr == "strange": - return 11 - elif checkStr == "haunted": - return 13 - elif checkStr == "collectors": - return 14 - elif checkStr == "paintkitweapon": - return 15 + try: + return self.qualitiesObj[string.lower()] + except: + return "" # - # Converts wear_tier string to wear_tier int + # Converts particle string to particle int # + def particle_String_To_Int(self, string): + try: + return self.particleObj[string.lower()] + except: + return "" - def wear_Tier_String_To_Int(self, string): - checkStr = string.lower() + # + # Converts rarity string to rarity int + # + def rarity_String_To_Int(self, string): + try: + return self.raritiesObj[string.lower()] + except: + return "" + + + # + # Origin quality string to origin int + # + def origin_String_To_Int(self, string): + try: + return self.originsObj[string.lower()] + except: + return "" - if checkStr == "factory new": - return 1 - elif checkStr == "minimal wear": - return 2 - elif checkStr == "field-tested": - return 3 - elif checkStr == "well-worn": - return 4 - elif checkStr == "battle scarred": - return 5 # - # Converts killstreaker tier string to killstreaker int + # Converts wear_tier string to wear_tier int # + def wear_tier_String_To_Int(self, string): + try: + return self.wear_tiersObj[string.lower()] + except: + return "" - def killstreaker_Tier_String_To_Int(self, string): - checkStr = string.lower() - if checkStr == "standard": - return 1 - elif checkStr == "specialized": - return 2 - elif checkStr == "professional": - return 3 + # + # Converts killstreaker string to killstreaker int + # + def killstreaker_String_To_Int(self, string): + try: + return self.killstreakers[string.lower()] + except: + return "" + + # # Converts sheen string to sheen int # - def sheen_String_To_Int(self, string): - checkStr = string.lower() - - if checkStr == "team shine": - return 1 - elif checkStr == "deadly daffodil": - return 2 - elif checkStr == "manndarin": - return 3 - elif checkStr == "mean green": - return 4 - elif checkStr == "agonizing emerald": - return 5 - elif checkStr == "villainous violet": - return 6 - elif checkStr == "hot rod": - return 7 + try: + return self.sheensObj[string.lower()] + except: + return "" + + + # + # Converts killstreak_tier string to killstreak_tier int + # + def killstreak_tier_String_To_Int(self, string): + try: + return self.killstreak_tiers[string.lower()] + except: + return "" + + + # + # Converts strange_part string to strange_part int + # + def strange_parts_String_To_Int(self, string): + try: + return self.strange_partsObj[string.lower()] + except: + return "" + + + # + # Converts paint string to paint int + # + def paint_String_To_Int(self, string): + try: + return self.paintsObj[string.lower()] + except: + return "" # diff --git a/README.md b/README.md index 749cad6..fd1582f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # BackpackTF-API This is an unoffical api wrapper for the Backpack.tf API in python. You can do a lot with this API keep reading for more information - [![GitHub release (latest by date)](https://img.shields.io/github/v/release/davidteather/BackpackTf-API)](https://github.com/davidteather/BackpackTf-API/releases) [![GitHub](https://img.shields.io/github/license/davidteather/BackpackTf-API)](https://github.com/davidteather/BackpackTf-API/blob/master/LICENSE) [![PyPI - Downloads](https://img.shields.io/pypi/dm/BackpackTF)](https://pypi.org/project/BackPackTF/) + [![GitHub release (latest by date)](https://img.shields.io/github/v/release/davidteather/BackpackTf-API)](https://github.com/davidteather/BackpackTf-API/releases) [![Build Status](https://travis-ci.com/davidteather/BackpackTf-API.svg?branch=master)](https://travis-ci.com/davidteather/BackpackTf-API) [![GitHub](https://img.shields.io/github/license/davidteather/BackpackTf-API)](https://github.com/davidteather/BackpackTf-API/blob/master/LICENSE) [![PyPI - Downloads](https://img.shields.io/pypi/dm/BackpackTF)](https://pypi.org/project/BackPackTF/) ## Important Information * If this API stops working for any reason open an issue. @@ -96,6 +96,19 @@ returns 0 or 1 for success or failure. returns a dictionary. [Here](https://gist.github.com/davidteather/109acc0acd7e7d59f8192d8d8cfcba7c)'s an example json + +#### extract_trade_url - extracts the trade url with token from a listing + + +| Attributes | Description | +| ------------- | ------------- | +| listingJSON | This is the json object of a classified listing on backpack.tf. You can get this using the method above. | +| proxy | This is an optional field, provide a dictionary that fits the python requests module requirements. See [here](https://stackoverflow.com/questions/8287628/proxies-with-python-requests-module) | + + +returns the trade url as a string. + + ### The Currency Class __init__ @@ -162,7 +175,7 @@ __init__ | Attributes | Description | | ------------- | ------------- | -| None | None | +| None | None | #### quality_String_To_Int @@ -170,43 +183,63 @@ __init__ | Attributes | Description | | ------------- | ------------- | -| string | The string of the quality. Ex: "unique" | +| string | The string of the quality. Ex: "unique" | + + +#### particle_String_To_Int + + +| Attributes | Description | +| ------------- | ------------- | +| string | The string of the particle effect. | + + +#### rarity_String_To_Int + + +| Attributes | Description | +| ------------- | ------------- | +| string | The string of the rarity. | + + +#### origin_String_To_Int + + +| Attributes | Description | +| ------------- | ------------- | +| string | The string of the origin. | -returns 0-15 -#### wear_Tier_String_To_Int +#### wear_tier_String_To_Int | Attributes | Description | | ------------- | ------------- | -| string | The string of the wear_tier. Ex: "factory new" | +| string | The string of the wear_tier. | -returns 1-5 -##### killstreaker_Tier_String_To_Int +#### killstreaker_String_To_Int | Attributes | Description | | ------------- | ------------- | -| string | The string of the killstreaker tier. Ex: "professional" | +| string | The string of the killstreaker. | -returns 1-3 -##### sheen_String_To_Int +#### strange_parts_String_To_Int | Attributes | Description | | ------------- | ------------- | -| string | The string of the sheen. Ex: "mean green" | +| string | The string of the strange part. | -return 1-7 #### steam_id_to_account_id | Attributes | Description | | ------------- | ------------- | -| string | The string of the steam_id. | +| string | The string of the steam_id. | returns an int of the account id. diff --git a/examples/extractTradeUrl.py b/examples/extractTradeUrl.py new file mode 100644 index 0000000..86f35c7 --- /dev/null +++ b/examples/extractTradeUrl.py @@ -0,0 +1,9 @@ +from BackpackTF.account import Account + +user = Account(client_id="xxxxxx", client_secret="xxxxxx", api_key="xxxxxx") + +classifieds = user.search_Classifieds()['buy']['listings'] + +for classified in classifieds: + trade_url = user.extract_trade_url(classified) + print(trade_url) \ No newline at end of file diff --git a/setup.py b/setup.py index 406773e..58ae985 100644 --- a/setup.py +++ b/setup.py @@ -8,24 +8,29 @@ setuptools.setup( name = 'BackpackTF', packages = ['BackpackTF'], - version = '0.0.1', + version = '0.1.0', license='MIT', description = 'The Unoffical Backpack.tf API Wrapper in Python 3.', author = 'David Teather', author_email = 'contact.davidteather@gmail.com', - url = 'https://github.com/davidteather/BackpackTF-Python', + url = 'https://github.com/davidteather/BackpackTf-API', long_description=long_description, long_description_content_type="text/markdown", - download_url = 'https://github.com/davidteather/BackpackTf-Python/tarball/master', + download_url = 'https://github.com/davidteather/BackpackTf-API/tarball/master', keywords = ['backpacktf', 'python3', 'tf2', 'unofficial', 'backpack.tf', 'trading-bot', 'api'], install_requires=[ - 'requests' + 'requests', + 'oauth2', + 'lxml' ], classifiers=[ 'Development Status :: 3 - Alpha', 'Intended Audience :: Developers', 'Topic :: Software Development :: Build Tools', 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3.7' + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.4' ], ) \ No newline at end of file diff --git a/tests/__pycache__/test_miscutils.cpython-37-pytest-5.1.2.pyc b/tests/__pycache__/test_miscutils.cpython-37-pytest-5.1.2.pyc new file mode 100644 index 0000000..42f09bc Binary files /dev/null and b/tests/__pycache__/test_miscutils.cpython-37-pytest-5.1.2.pyc differ diff --git a/tests/__pycache__/test_misutils.cpython-37-pytest-5.1.2.pyc b/tests/__pycache__/test_misutils.cpython-37-pytest-5.1.2.pyc new file mode 100644 index 0000000..874e953 Binary files /dev/null and b/tests/__pycache__/test_misutils.cpython-37-pytest-5.1.2.pyc differ diff --git a/tests/test_miscutils.py b/tests/test_miscutils.py new file mode 100644 index 0000000..9d83aba --- /dev/null +++ b/tests/test_miscutils.py @@ -0,0 +1,110 @@ +from BackpackTF import MiscUtils + +def test_quality_to_int(): + misc = MiscUtils() + + assert misc.quality_String_To_Int("Collector's") == 14 + assert misc.quality_String_To_Int("Decorated Weapon") == 15 + assert misc.quality_String_To_Int("Genuine") == 1 + assert misc.quality_String_To_Int("Haunted") == 13 + assert misc.quality_String_To_Int("Normal") == 0 + assert misc.quality_String_To_Int("Self-Made") == 9 + assert misc.quality_String_To_Int("Strange") == 11 + assert misc.quality_String_To_Int("Unique") == 6 + assert misc.quality_String_To_Int("Unusual") == 5 + assert misc.quality_String_To_Int("Vintage") == 3 + +def test_particle_to_int(): + misc = MiscUtils() + + assert misc.particle_String_To_Int("Abduction") == 91 + assert misc.particle_String_To_Int("Aces High") == 59 + assert misc.particle_String_To_Int("Acidic Bubbles of Envy") == 3017 + assert misc.particle_String_To_Int("Amaranthine") == 82 + assert misc.particle_String_To_Int("Bubbling") == 34 + assert misc.particle_String_To_Int("Burning Flames") == 13 + assert misc.particle_String_To_Int("Cauldron Bubbles") == 39 + assert misc.particle_String_To_Int("Cool") == 703 + assert misc.particle_String_To_Int("Dead Presidents") == 60 + +def test_rarity_to_int(): + misc = MiscUtils() + + assert misc.rarity_String_To_Int("") == 99 + assert misc.rarity_String_To_Int("Assassin") == 5 + assert misc.rarity_String_To_Int("Civilian") == 1 + assert misc.rarity_String_To_Int("Elite") == 6 + assert misc.rarity_String_To_Int("Freelance") == 2 + assert misc.rarity_String_To_Int("Immortal") == 7 + +def test_origin_to_int(): + misc = MiscUtils() + + assert misc.origin_String_To_Int("Achievement") == 1 + assert misc.origin_String_To_Int("CD Key") == 15 + assert misc.origin_String_To_Int("Collection Reward") == 16 + assert misc.origin_String_To_Int("Earned") == 9 + assert misc.origin_String_To_Int("Gifted") == 6 + +def test_wear_tier_to_int(): + misc = MiscUtils() + + assert misc.wear_tier_String_To_Int("Factory New") == 1 + assert misc.wear_tier_String_To_Int("Minimal Wear") == 2 + assert misc.wear_tier_String_To_Int("Field-Tested") == 3 + assert misc.wear_tier_String_To_Int("Well-Worn") == 4 + assert misc.wear_tier_String_To_Int("Battle Scarred") == 5 + +def test_killstreaker_to_int(): + misc = MiscUtils() + + assert misc.killstreaker_String_To_Int("Fire Horns") == 2002 + assert misc.killstreaker_String_To_Int("Cerebral Discharge") == 2003 + assert misc.killstreaker_String_To_Int("Tornado") == 2004 + assert misc.killstreaker_String_To_Int("Flames") == 2005 + assert misc.killstreaker_String_To_Int("Singularity") == 2006 + assert misc.killstreaker_String_To_Int("Incinerator") == 2007 + +def test_sheen_to_int(): + misc = MiscUtils() + + assert misc.sheen_String_To_Int("Team Shine") == 1 + assert misc.sheen_String_To_Int("Deadly Daffodil") == 2 + assert misc.sheen_String_To_Int("Manndarin") == 3 + assert misc.sheen_String_To_Int("Mean Green") == 4 + assert misc.sheen_String_To_Int("Agonizing Emerald") == 5 + assert misc.sheen_String_To_Int("Villainous Violet") == 6 + assert misc.sheen_String_To_Int("Hot Rod") == 7 + +def test_Killstreak_tier_to_int(): + misc = MiscUtils() + + assert misc.killstreak_tier_String_To_Int("None") == 0 + assert misc.killstreak_tier_String_To_Int("Standard") == 1 + assert misc.killstreak_tier_String_To_Int("Specialized") == 2 + assert misc.killstreak_tier_String_To_Int("Professional") == 3 + +def test_strange_parts_to_int(): + misc = MiscUtils() + + assert misc.strange_parts_String_To_Int("Airborne Enemies Killed") == 22 + assert misc.strange_parts_String_To_Int("Allied Healing Done") == 84 + assert misc.strange_parts_String_To_Int("Assists") == 95 + assert misc.strange_parts_String_To_Int("Critical Kills") == 33 + assert misc.strange_parts_String_To_Int("Damage Dealt") == 82 + +def test_paint_to_Int(): + misc = MiscUtils() + + assert misc.paint_String_To_Int("A Color Similar to Slate") == 3100495 + assert misc.paint_String_To_Int("A Deep Commitment to Purple") == 8208497 + assert misc.paint_String_To_Int("A Distinctive Lack of Hue") == 1315860 + assert misc.paint_String_To_Int("A Mann's Mint") == 12377523 + assert misc.paint_String_To_Int("After Eight") == 2960676 + assert misc.paint_String_To_Int("Aged Moustache Grey") == 8289918 + +def test_steam_id_to_account_id(): + misc = MiscUtils() + + assert misc.steam_id_to_account_id("76561198195716551") == "235450823" +