├── .gitignore ├── LICENSE.txt ├── README.md ├── docs └── conf.py ├── drivers ├── Darwin │ ├── chromedriver │ └── geckodriver └── Linux │ ├── chromedriver │ └── geckodriver ├── requirements.txt ├── setup.py ├── supremeBot ├── __init__.py ├── helpers.py └── main.py └── tests ├── test_advanced.py └── test_basic.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | ./supremeBot/__pycache__/ 3 | *.pyo 4 | *.pyc 5 | ./supremeBot/geckodriver.log 6 | 7 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | Copyright (c) 2018 Nichlas Langhoff Rasmussen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 21 | OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Outdated 2 | Once in a while I get a message regarding this bot and issues with getting it to run. This bot was one of the first things I wrote in Python back in the beginning of high school. It is super outdated and the Supreme shop has had many updates since then. 3 | 4 | # supremeBot 5 | Use this bot at your own risk (Supreme may not accept orders from bots as of SS18, and might ban your ip). 6 | The bot can be used rather than you having to pay 100$ for one. 7 | 8 | # TODO: 9 | - [x] Add OS check and load corresponding webdrivers. 10 | - [x] Continously refresh site close to drop 11 | - [ ] Script to add drivers to path. 12 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lrnq/supremeBot/d0d3d236dbc61fb7c2293f26e1cf37a13cf98b74/docs/conf.py -------------------------------------------------------------------------------- /drivers/Darwin/chromedriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lrnq/supremeBot/d0d3d236dbc61fb7c2293f26e1cf37a13cf98b74/drivers/Darwin/chromedriver -------------------------------------------------------------------------------- /drivers/Darwin/geckodriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lrnq/supremeBot/d0d3d236dbc61fb7c2293f26e1cf37a13cf98b74/drivers/Darwin/geckodriver -------------------------------------------------------------------------------- /drivers/Linux/chromedriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lrnq/supremeBot/d0d3d236dbc61fb7c2293f26e1cf37a13cf98b74/drivers/Linux/chromedriver -------------------------------------------------------------------------------- /drivers/Linux/geckodriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lrnq/supremeBot/d0d3d236dbc61fb7c2293f26e1cf37a13cf98b74/drivers/Linux/geckodriver -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | splinter 2 | bs4 3 | requests 4 | lxml 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Note: To use the 'upload' functionality of this file, you must: 5 | # $ pip install twine 6 | 7 | import io 8 | import os 9 | import sys 10 | from shutil import rmtree 11 | 12 | from setuptools import find_packages, setup, Command 13 | 14 | # Package meta-data. 15 | NAME = 'Supreme Bot' 16 | DESCRIPTION = 'A bot for buying things on supreme when things drop' 17 | URL = 'https://github.com/quantzz/supremeBot.git' 18 | EMAIL = 'nichlas@mlblog.io' 19 | AUTHOR = 'Nichlas Langhoff Rasmussen' 20 | REQUIRES_PYTHON = '>=3.6.0' 21 | VERSION = 0.1 22 | 23 | REQUIRED = [ 24 | 'requests', 'bs4', 'splinter', 25 | ] 26 | 27 | here = os.path.abspath(os.path.dirname(__file__)) 28 | 29 | try: 30 | with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f: 31 | long_description = '\n' + f.read() 32 | except FileNotFoundError: 33 | long_description = DESCRIPTION 34 | 35 | # Load the package's __version__.py module as a dictionary. 36 | about = {} 37 | if not VERSION: 38 | with open(os.path.join(here, NAME, '__version__.py')) as f: 39 | exec(f.read(), about) 40 | else: 41 | about['__version__'] = VERSION 42 | 43 | 44 | class UploadCommand(Command): 45 | """Support setup.py upload.""" 46 | 47 | description = 'Build and publish the package.' 48 | user_options = [] 49 | 50 | @staticmethod 51 | def status(s): 52 | """Prints things in bold.""" 53 | print('\033[1m{0}\033[0m'.format(s)) 54 | 55 | def initialize_options(self): 56 | pass 57 | 58 | def finalize_options(self): 59 | pass 60 | 61 | def run(self): 62 | try: 63 | self.status('Removing previous builds…') 64 | rmtree(os.path.join(here, 'dist')) 65 | except OSError: 66 | pass 67 | 68 | self.status('Building Source and Wheel (universal) distribution…') 69 | os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable)) 70 | 71 | self.status('Uploading the package to PyPI via Twine…') 72 | os.system('twine upload dist/*') 73 | 74 | self.status('Pushing git tags…') 75 | os.system('git tag v{0}'.format(about['__version__'])) 76 | os.system('git push --tags') 77 | 78 | sys.exit() 79 | 80 | 81 | setup( 82 | name=NAME, 83 | version=about['__version__'], 84 | description=DESCRIPTION, 85 | long_description=long_description, 86 | long_description_content_type='text/markdown', 87 | author=AUTHOR, 88 | author_email=EMAIL, 89 | python_requires=REQUIRES_PYTHON, 90 | url=URL, 91 | packages=find_packages(exclude=('tests',)), 92 | # If your package is a single module, use this instead of 'packages': 93 | # py_modules=['mypackage'], 94 | 95 | # entry_points={ 96 | # 'console_scripts': ['mycli=mymodule:cli'], 97 | # }, 98 | install_requires=REQUIRED, 99 | extras_require=EXTRAS, 100 | include_package_data=True, 101 | license='MIT', 102 | classifiers=[ 103 | # Trove classifiers 104 | # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers 105 | 'License :: OSI Approved :: MIT License', 106 | 'Programming Language :: Python', 107 | 'Programming Language :: Python :: 3', 108 | 'Programming Language :: Python :: 3.6', 109 | 'Programming Language :: Python :: Implementation :: CPython', 110 | 'Programming Language :: Python :: Implementation :: PyPy' 111 | ], 112 | # $ setup.py publish support. 113 | cmdclass={ 114 | 'upload': UploadCommand, 115 | }, 116 | ) 117 | -------------------------------------------------------------------------------- /supremeBot/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lrnq/supremeBot/d0d3d236dbc61fb7c2293f26e1cf37a13cf98b74/supremeBot/__init__.py -------------------------------------------------------------------------------- /supremeBot/helpers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import platform 4 | import glob 5 | 6 | 7 | def get_driver_path(driver): 8 | supported = ["Darwin", "Linux"] 9 | op = platform.platform().split("-") 10 | if "x86_64" not in op: 11 | os.error("32-bit is not supported at the moment") 12 | 13 | if op[0] in supported: 14 | relative_path = "../drivers/{}/{}".format(op[0], driver) 15 | return relative_path 16 | 17 | 18 | if __name__ == "__main__": 19 | print(get_driver_path("geckodriver")) 20 | 21 | -------------------------------------------------------------------------------- /supremeBot/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import requests 3 | import bs4 as bs 4 | from splinter import Browser 5 | import helpers 6 | 7 | 8 | class supremeBot(object): 9 | def __init__(self, **info): 10 | self.base_url = 'http://www.supremenewyork.com/' 11 | self.shop = 'shop/all/' 12 | self.checkout = 'checkout/' 13 | self.info = info 14 | 15 | def initializeBrowser(self): 16 | driver = self.info["driver"] 17 | path = helpers.get_driver_path(driver) 18 | if driver == "geckodriver": 19 | self.b = Browser() 20 | elif driver == "chromedriver": 21 | executable_path = {"executable_path": path} 22 | self.b = Browser('chrome', **executable_path) 23 | 24 | 25 | def findProduct(self): 26 | try: 27 | r = requests.get( 28 | "{}{}{}".format( 29 | self.base_url, 30 | self.shop, 31 | self.info['category'])).text 32 | soup = bs.BeautifulSoup(r, 'lxml') 33 | 34 | temp_tuple = [] 35 | temp_link = [] 36 | 37 | for link in soup.find_all('a', href=True): 38 | temp_tuple.append((link['href'], link.text)) 39 | for i in temp_tuple: 40 | if i[1] == self.info['product'] or i[1] == self.info['color']: 41 | temp_link.append(i[0]) 42 | 43 | self.final_link = list( 44 | set([x for x in temp_link if temp_link.count(x) == 2]))[0] 45 | return True 46 | except: 47 | return False 48 | 49 | def visitSite(self): 50 | self.b.visit( 51 | "{}{}".format( 52 | self.base_url, str( 53 | self.final_link))) 54 | self.b.find_option_by_text(self.info['size']).click() 55 | self.b.find_by_value('add to basket').click() 56 | 57 | def checkoutFunc(self): 58 | 59 | self.b.visit("{}{}".format(self.base_url, self.checkout)) 60 | 61 | self.b.fill("order[billing_name]", self.info['namefield']) 62 | self.b.fill("order[email]", self.info['emailfield']) 63 | self.b.fill("order[tel]", self.info['phonefield']) 64 | 65 | self.b.fill("order[billing_address]", self.info['addressfield']) 66 | self.b.fill("order[billing_city]", self.info['city']) 67 | self.b.fill("order[billing_zip]", self.info['zip']) 68 | self.b.select("order[billing_country]", self.info['country']) 69 | 70 | self.b.select("credit_card[type]", self.info['card']) 71 | self.b.fill("credit_card[cnb]", self.info['number']) 72 | self.b.select("credit_card[month]", self.info['month']) 73 | self.b.select("credit_card[year]", self.info['year']) 74 | self.b.fill("credit_card[ovv]", self.info['ccv']) 75 | self.b.find_by_css('.terms').click() 76 | #self.b.find_by_value("process payment").click() 77 | 78 | 79 | if __name__ == "__main__": 80 | INFO = { 81 | "driver": "geckodriver", 82 | "product": "Thermal Zip Up Hooded Sweatshirt", 83 | "color": "Tangerine", 84 | "size": "Medium", 85 | "category": "sweatshirts", 86 | "namefield": "example", 87 | "emailfield": "example@example.com", 88 | "phonefield": "XXXXXXXXXX", 89 | "addressfield": "example road", 90 | "city": "example", 91 | "zip": "72046", 92 | "country": "GB", 93 | "card": "visa", 94 | "number": "1234123412341234", 95 | "month": "09", 96 | "year": "2020", 97 | "ccv": "123" 98 | } 99 | BOT = supremeBot(**INFO) 100 | # Flag to set to true if you want to reload the page continously close to drop. 101 | found_product = False 102 | max_iter = 10 103 | counter = 1 104 | while not found_product and counter < max_iter: 105 | found_product = BOT.findProduct() 106 | print("Tried ", counter, " times") 107 | counter += 1 108 | if not found_product: 109 | raise Exception("Couldn't find product. Sry bruh") 110 | BOT.initializeBrowser() 111 | BOT.visitSite() 112 | BOT.checkoutFunc() 113 | -------------------------------------------------------------------------------- /tests/test_advanced.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lrnq/supremeBot/d0d3d236dbc61fb7c2293f26e1cf37a13cf98b74/tests/test_advanced.py -------------------------------------------------------------------------------- /tests/test_basic.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lrnq/supremeBot/d0d3d236dbc61fb7c2293f26e1cf37a13cf98b74/tests/test_basic.py --------------------------------------------------------------------------------