├── data
├── tasks.json
├── profiles.json
├── proxies.json
├── .DS_Store
└── settings.json
├── .gitignore
├── images
├── edit.png
└── birdbot.png
├── pages
├── .DS_Store
├── createdialog.py
├── settingspage.py
├── proxiespage.py
├── homepage.py
└── profilespage.py
├── sites
├── .DS_Store
├── walmart.py
├── bestbuy.py
└── walmart_encryption.py
├── requirements.txt
├── settings.py
├── README.md
├── LICENSE
├── webhook.py
├── utils.py
├── app.py
└── encrypt.js
/data/tasks.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/data/profiles.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/data/proxies.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | data/profiles.json
2 | data/proxies.json
3 |
--------------------------------------------------------------------------------
/data/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natewong1313/bird-bot/HEAD/data/.DS_Store
--------------------------------------------------------------------------------
/images/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natewong1313/bird-bot/HEAD/images/edit.png
--------------------------------------------------------------------------------
/pages/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natewong1313/bird-bot/HEAD/pages/.DS_Store
--------------------------------------------------------------------------------
/sites/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natewong1313/bird-bot/HEAD/sites/.DS_Store
--------------------------------------------------------------------------------
/images/birdbot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natewong1313/bird-bot/HEAD/images/birdbot.png
--------------------------------------------------------------------------------
/data/settings.json:
--------------------------------------------------------------------------------
1 | {"webhook": "", "webhookonbrowser": true, "webhookonorder": true, "webhookonfailed": true, "browseronfailed": true, "onlybuyone": true}
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pyqt5==5.14.2
2 | js2py==0.68
3 | requests==2.23.0
4 | lxml==4.5.0
5 | darkdetect==0.1.1
6 | colorama==0.4.3
7 | selenium==3.141.0
8 | chromedriver-py==81.0.4044.69
9 | pycryptodome==3.4.3
10 |
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | global webhook
2 | webhook = ""
3 | global webhook_on_browser
4 | webhook_on_browser = True
5 | global webhook_on_order
6 | webhook_on_order = True
7 | global webhook_on_failed
8 | webhook_on_failed = True
9 | global browser_on_failed
10 | browser_on_failed = True
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Bird Bot
2 | [Support Discord](https://discord.gg/kfAqBKv)
3 | Bird Bot is an auto-checkout bot that currently supports Walmart and Best buy. It is intended to be used to purchase Nintendo Switch consoles. More sites will be added in the future.
4 |
5 | * Easy to use interface built on PyQt5
6 | * Waits for items to restock if they are out of stock
7 | * Optional price checker
8 | * Lighting fast auto-checkout
9 |
10 |
11 |
12 |
13 |
14 | ## Installation
15 | [View The Docs Here](https://nateskicks13.gitbook.io/bird-bot/)
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Nate
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, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/webhook.py:
--------------------------------------------------------------------------------
1 | import requests, time, datetime, json
2 |
3 | #modified from https://github.com/lovvskillz/python-discord-webhook
4 |
5 | class DiscordWebhook:
6 | def __init__(self, url, **kwargs):
7 | self.url = url
8 | self.content = kwargs.get("content")
9 | self.username = kwargs.get("username")
10 | self.avatar_url = kwargs.get("avatar_url")
11 | self.tts = kwargs.get("tts", False)
12 | self.files = kwargs.get("files", dict())
13 | self.embeds = kwargs.get("embeds", [])
14 | self.proxies = kwargs.get("proxies", None)
15 |
16 | def add_file(self, file, filename):
17 | self.files["_{}".format(filename)] = (filename, file)
18 |
19 | def add_embed(self, embed):
20 | self.embeds.append(embed.__dict__ if isinstance(embed, DiscordEmbed) else embed)
21 |
22 | def remove_embed(self, index):
23 | self.embeds.pop(index)
24 |
25 | def get_embeds(self):
26 | return self.embeds
27 |
28 | def set_proxies(self, proxies):
29 | self.proxies = proxies
30 |
31 | @property
32 | def json(self):
33 | data = dict()
34 | embeds = self.embeds
35 | self.embeds = list()
36 | for embed in embeds:
37 | self.add_embed(embed)
38 | for key, value in self.__dict__.items():
39 | if value and key not in ["url", "files", "filename"]:
40 | data[key] = value
41 | embeds_empty = all(not embed for embed in data["embeds"]) if "embeds" in data else True
42 | return data
43 |
44 | def execute(self):
45 | if bool(self.files) is False:
46 | response = requests.post(self.url, json=self.json, proxies=self.proxies)
47 | else:
48 | self.files["payload_json"] = (None, json.dumps(self.json))
49 | response = requests.post(self.url, files=self.files, proxies=self.proxies)
50 |
51 |
52 | class DiscordEmbed:
53 | def __init__(self, **kwargs):
54 | self.title = kwargs.get("title")
55 | self.description = kwargs.get("description")
56 | self.url = kwargs.get("url")
57 | self.timestamp = kwargs.get("timestamp")
58 | self.color = kwargs.get("color")
59 | self.footer = kwargs.get("footer")
60 | self.image = kwargs.get("image")
61 | self.thumbnail = kwargs.get("thumbnail")
62 | self.video = kwargs.get("video")
63 | self.provider = kwargs.get("provider")
64 | self.author = kwargs.get("author")
65 | self.fields = kwargs.get("fields", [])
66 |
67 | def set_title(self, title):
68 | self.title = title
69 |
70 | def set_description(self, description):
71 | self.description = description
72 |
73 | def set_url(self, url):
74 | self.url = url
75 |
76 | def set_timestamp(self, timestamp=str(datetime.datetime.utcfromtimestamp(time.time()))):
77 | self.timestamp = timestamp
78 |
79 | def set_color(self, color):
80 | self.color = color
81 |
82 | def set_footer(self, **kwargs):
83 | self.footer = {
84 | "text": kwargs.get("text"),
85 | "icon_url": kwargs.get("icon_url"),
86 | "proxy_icon_url": kwargs.get("proxy_icon_url")
87 | }
88 |
89 | def set_image(self, **kwargs):
90 | self.image = {
91 | "url": kwargs.get("url"),
92 | "proxy_url": kwargs.get("proxy_url"),
93 | "height": kwargs.get("height"),
94 | "width": kwargs.get("width"),
95 | }
96 |
97 | def set_thumbnail(self, **kwargs):
98 | self.thumbnail = {
99 | "url": kwargs.get("url"),
100 | "proxy_url": kwargs.get("proxy_url"),
101 | "height": kwargs.get("height"),
102 | "width": kwargs.get("width"),
103 | }
104 |
105 | def set_video(self, **kwargs):
106 | self.video = {
107 | "url": kwargs.get("url"),
108 | "height": kwargs.get("height"),
109 | "width": kwargs.get("width"),
110 | }
111 |
112 | def set_provider(self, **kwargs):
113 | self.provider = {
114 | "name": kwargs.get("name"),
115 | "url": kwargs.get("url"),
116 | }
117 |
118 | def set_author(self, **kwargs):
119 | self.author = {
120 | "name": kwargs.get("name"),
121 | "url": kwargs.get("url"),
122 | "icon_url": kwargs.get("icon_url"),
123 | "proxy_icon_url": kwargs.get("proxy_icon_url"),
124 | }
125 |
126 | def add_embed_field(self, **kwargs):
127 | self.fields.append({
128 | "name": kwargs.get("name"),
129 | "value": kwargs.get("value"),
130 | "inline": kwargs.get("inline", True)
131 | })
132 |
133 | def del_embed_field(self, index):
134 | self.fields.pop(index)
135 |
136 | def get_embed_fields(self):
137 | return self.fields
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | try:
2 | from Crypto import Random
3 | from Crypto.Cipher import AES
4 | except:
5 | from Cryptodome import Random
6 | from Cryptodome.Cipher import AES
7 | from colorama import init, Fore, Back, Style
8 | from datetime import datetime
9 | from selenium.webdriver import Chrome, ChromeOptions
10 | from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
11 | from webhook import DiscordWebhook, DiscordEmbed
12 | from chromedriver_py import binary_path as driver_path
13 | import json, platform, darkdetect, random, settings, threading, hashlib, base64
14 | normal_color = Fore.CYAN
15 | e_key = "YnJ1aG1vbWVudA==".encode()
16 | BLOCK_SIZE=16
17 | if platform.system() == "Windows":
18 | init(convert=True)
19 | else:
20 | init()
21 | print(normal_color + "Welcome To Bird Bot")
22 |
23 | class BirdLogger:
24 | def ts(self):
25 | return str(datetime.now())[:-7]
26 | def normal(self,task_id,msg):
27 | print(normal_color + "[{}][TASK {}] {}".format(self.ts(),task_id,msg))
28 | def alt(self,task_id,msg):
29 | print(Fore.MAGENTA + "[{}][TASK {}] {}".format(self.ts(),task_id,msg))
30 | def error(self,task_id,msg):
31 | print(Fore.RED + "[{}][TASK {}] {}".format(self.ts(),task_id,msg))
32 | def success(self,task_id,msg):
33 | print(Fore.GREEN + "[{}][TASK {}] {}".format(self.ts(),task_id,msg))
34 | class Encryption:
35 | def encrypt(self,msg):
36 | IV = Random.new().read(BLOCK_SIZE)
37 | aes = AES.new(self.trans(e_key), AES.MODE_CFB, IV)
38 | return base64.b64encode(IV + aes.encrypt(msg.encode("utf-8")))
39 | def decrypt(self,msg):
40 | msg = base64.b64decode(msg)
41 | IV = msg[:BLOCK_SIZE]
42 | aes = AES.new(self.trans(e_key), AES.MODE_CFB, IV)
43 | return aes.decrypt(msg[BLOCK_SIZE:])
44 | def trans(self,key):
45 | return hashlib.md5(key).digest()
46 | def return_data(path):
47 | with open(path,"r") as file:
48 | data = json.load(file)
49 | file.close()
50 | return data
51 | def write_data(path,data):
52 | with open(path, "w") as file:
53 | json.dump(data, file)
54 | file.close()
55 | def get_profile(profile_name):
56 | profiles = return_data("./data/profiles.json")
57 | for p in profiles:
58 | if p["profile_name"] == profile_name:
59 | try:
60 | p["card_number"] = (Encryption().decrypt(p["card_number"].encode("utf-8"))).decode("utf-8")
61 | except ValueError:
62 | pass
63 | return p
64 | return None
65 | def get_proxy(list_name):
66 | if list_name == "Proxy List" or list_name == "None":
67 | return False
68 | proxies = return_data("./data/proxies.json")
69 | for proxy_list in proxies:
70 | if proxy_list["list_name"] == list_name:
71 | return format_proxy(random.choice(proxy_list["proxies"].splitlines()))
72 | return None
73 | def format_proxy(proxy):
74 | try:
75 | proxy_parts = proxy.split(":")
76 | ip, port, user, passw = proxy_parts[0], proxy_parts[1], proxy_parts[2], proxy_parts[3]
77 | return {
78 | "http": "http://{}:{}@{}:{}".format(user, passw, ip, port),
79 | "https": "https://{}:{}@{}:{}".format(user, passw, ip, port)
80 | }
81 | except IndexError:
82 | return {"http": "http://" + proxy, "https": "https://" + proxy}
83 | def send_webhook(webhook_type,site,profile,task_id,image_url):
84 | if settings.webhook !="":
85 | webhook = DiscordWebhook(url=settings.webhook, username="Bird Bot", avatar_url="https://i.imgur.com/fy26LbM.png")
86 | if webhook_type == "OP":
87 | if not settings.webhook_on_order:
88 | return
89 | embed = DiscordEmbed(title="Order Placed",color=0x34c693)
90 | elif webhook_type == "B":
91 | if not settings.webhook_on_browser:
92 | return
93 | embed = DiscordEmbed(title="Complete Order in Browser",color=0xf2a689)
94 | elif webhook_type == "PF":
95 | if not settings.webhook_on_failed:
96 | return
97 | embed = DiscordEmbed(title="Payment Failed",color=0xfc5151)
98 | embed.set_footer(text="Via Bird Bot",icon_url="https://i.imgur.com/fy26LbM.png")
99 | embed.add_embed_field(name="Site", value=site,inline=True)
100 | embed.add_embed_field(name="Profile", value=profile,inline=True)
101 | embed.add_embed_field(name="Task ID", value=task_id,inline=True)
102 | embed.set_thumbnail(url=image_url)
103 | webhook.add_embed(embed)
104 | try:
105 | webhook.execute()
106 | except:
107 | pass
108 |
109 | def open_browser(link,cookies):
110 | threading.Thread(target = start_browser, args=(link,cookies)).start()
111 |
112 | def start_browser(link,cookies):
113 | caps = DesiredCapabilities().CHROME
114 | caps["pageLoadStrategy"] = "eager"
115 | chrome_options = ChromeOptions()
116 | chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
117 | chrome_options.add_experimental_option("useAutomationExtension", False)
118 | driver = Chrome(desired_capabilities=caps, executable_path=driver_path, options=chrome_options)
119 | driver.execute_cdp_cmd(
120 | "Page.addScriptToEvaluateOnNewDocument",
121 | {
122 | "source": """
123 | Object.defineProperty(window, 'navigator', {
124 | value: new Proxy(navigator, {
125 | has: (target, key) => (key === 'webdriver' ? false : key in target),
126 | get: (target, key) =>
127 | key === 'webdriver'
128 | ? undefined
129 | : typeof target[key] === 'function'
130 | ? target[key].bind(target)
131 | : target[key]
132 | })
133 | })
134 | """
135 | },
136 | )
137 | driver.get(link)
138 | for cookie in cookies:
139 | driver.add_cookie({
140 | "name": cookie["name"],
141 | "value" : cookie["value"],
142 | "domain" : cookie["domain"]
143 | })
144 | driver.get(link)
145 |
--------------------------------------------------------------------------------
/pages/createdialog.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import QtCore, QtGui, QtWidgets
2 | import sys,platform
3 | def no_abort(a, b, c):
4 | sys.__excepthook__(a, b, c)
5 | sys.excepthook = no_abort
6 |
7 | class CreateDialog(QtWidgets.QDialog):
8 | def __init__(self,parent=None):
9 | super(CreateDialog, self).__init__(parent)
10 | self.setupUi(self)
11 | self.show()
12 | def setupUi(self, CreateDialog):
13 | self.CreateDialog = CreateDialog
14 | CreateDialog.setFixedSize(647, 164)
15 | CreateDialog.setStyleSheet("QComboBox::drop-down { border: 0px;}QComboBox::down-arrow { image: url(:/images/down_icon.png); width: 14px; height: 14px;}QComboBox{ padding: 1px 0px 1px 3px;}QLineEdit:focus { border: none; outline: none;} QSpinBox::up-button {subcontrol-origin: border;subcontrol-position: top right;width: 8px; border-image: url(:/images/uparrow_icon.png) 1;border-width: 1px;}QSpinBox::down-button {subcontrol-origin: border;subcontrol-position: bottom right;width: 8px;border-image: url(:/images/downarrow_icon.png) 1;border-width: 1px;border-top-width: 0;}")
16 | CreateDialog.setWindowTitle("Create Tasks")
17 | self.background = QtWidgets.QWidget(CreateDialog)
18 | self.background.setGeometry(QtCore.QRect(0, 0, 691, 391))
19 | self.background.setStyleSheet("background-color: #1E1E1E;")
20 | font = QtGui.QFont()
21 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
22 | font.setFamily("Arial")
23 | self.site_box = QtWidgets.QComboBox(self.background)
24 | self.site_box.setGeometry(QtCore.QRect(50, 20, 151, 21))
25 | self.site_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
26 | self.site_box.addItem("Site")
27 | self.site_box.setFont(font)
28 | self.input_edit = QtWidgets.QLineEdit(self.background)
29 | self.input_edit.setGeometry(QtCore.QRect(250, 20, 151, 21))
30 | self.input_edit.setFocusPolicy(QtCore.Qt.ClickFocus)
31 | self.input_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
32 | self.input_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
33 | self.input_edit.setPlaceholderText("Link")
34 | self.input_edit.setFont(font)
35 | self.input_edit.textEdited.connect(self.autofill)
36 | self.profile_box = QtWidgets.QComboBox(self.background)
37 | self.profile_box.setGeometry(QtCore.QRect(450, 20, 151, 21))
38 | self.profile_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
39 | self.profile_box.addItem("Profile")
40 | self.profile_box.setFont(font)
41 | self.proxies_box = QtWidgets.QComboBox(self.background)
42 | self.proxies_box.setGeometry(QtCore.QRect(450, 70, 151, 21))
43 | self.proxies_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
44 | self.proxies_box.addItem("Proxy List")
45 | self.proxies_box.addItem("None")
46 | self.proxies_box.setFont(font)
47 | self.monitor_edit = QtWidgets.QLineEdit(self.background)
48 | self.monitor_edit.setGeometry(QtCore.QRect(50, 70, 61, 21))
49 | self.monitor_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
50 | self.monitor_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
51 | self.monitor_edit.setPlaceholderText("Monitor")
52 | self.monitor_edit.setFont(font)
53 | self.monitor_edit.setText("5.0")
54 | self.only_float = QtGui.QDoubleValidator()
55 | self.monitor_edit.setValidator(self.only_float)
56 | self.error_edit = QtWidgets.QLineEdit(self.background)
57 | self.error_edit.setGeometry(QtCore.QRect(140, 70, 61, 21))
58 | self.error_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
59 | self.error_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
60 | self.error_edit.setPlaceholderText("Error")
61 | self.error_edit.setFont(font)
62 | self.error_edit.setText("5.0")
63 | self.error_edit.setValidator(self.only_float)
64 | self.addtask_btn = QtWidgets.QPushButton(self.background)
65 | self.addtask_btn.setGeometry(QtCore.QRect(250, 110, 151, 32))
66 | self.addtask_btn.setText("Add Task")
67 | self.maxprice_checkbox = QtWidgets.QCheckBox(self.background)
68 | self.maxprice_checkbox.setGeometry(QtCore.QRect(250, 70, 87, 20))
69 | font = QtGui.QFont()
70 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
71 | font.setFamily("Arial")
72 | self.maxprice_checkbox.setFont(font)
73 | self.maxprice_checkbox.setStyleSheet("color: #FFFFFF;")
74 | self.maxprice_checkbox.setText("Max Price")
75 | self.price_edit = QtWidgets.QLineEdit(self.background)
76 | self.price_edit.setGeometry(QtCore.QRect(350, 70, 51, 21))
77 | self.price_edit.setFont(font)
78 | self.price_edit.setFocusPolicy(QtCore.Qt.ClickFocus)
79 | self.price_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
80 | self.price_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
81 | self.only_int = QtGui.QIntValidator()
82 | self.price_edit.setValidator(self.only_int)
83 | font = QtGui.QFont()
84 | font.setFamily("Arial")
85 | font.setPointSize(14) if platform.system() == "Darwin" else font.setPointSize(14*.75)
86 | self.addtask_btn.setFont(font)
87 | self.addtask_btn.setStyleSheet("border-radius: 10px;background-color: #5D43FB;color: #FFFFFF;")
88 | self.addtask_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
89 | self.taskcount_spinbox = QtWidgets.QSpinBox(self.background)
90 | self.taskcount_spinbox.setGeometry(QtCore.QRect(420, 115, 41, 21))
91 | self.taskcount_spinbox.setStyleSheet("border: 1px solid #5D43FB;border-width: 0 0 2px;color: #FFFFFF;")
92 | self.taskcount_spinbox.setMinimum(1)
93 | self.taskcount_spinbox.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
94 |
95 | self.site_box.addItem("Bestbuy")
96 | self.site_box.addItem("Walmart")
97 |
98 | QtCore.QMetaObject.connectSlotsByName(CreateDialog)
99 | def autofill(self):
100 | if "bestbuy" in self.input_edit.text():
101 | self.site_box.setCurrentIndex(self.site_box.findText("Bestbuy"))
102 | elif "walmart" in self.input_edit.text():
103 | self.site_box.setCurrentIndex(self.site_box.findText("Walmart"))
104 |
105 | def load_data(self, task_tab):
106 | self.site_box.setCurrentText(task_tab.site)
107 | self.input_edit.setText(task_tab.product)
108 | self.profile_box.setCurrentText(task_tab.profile)
109 | self.proxies_box.setCurrentText(task_tab.proxies)
110 | self.monitor_edit.setText(task_tab.monitor_delay)
111 | self.error_edit.setText(task_tab.error_delay)
112 | self.price_edit.setText(task_tab.max_price)
113 | self.maxprice_checkbox.setChecked(task_tab.max_price is not '')
114 | self.addtask_btn.setText('Update Task')
115 |
116 |
117 |
--------------------------------------------------------------------------------
/pages/settingspage.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import QtCore, QtGui, QtWidgets
2 | from utils import return_data,write_data
3 | import sys,platform,settings
4 | def no_abort(a, b, c):
5 | sys.__excepthook__(a, b, c)
6 | sys.excepthook = no_abort
7 |
8 | class SettingsPage(QtWidgets.QWidget):
9 | def __init__(self,parent=None):
10 | super(SettingsPage, self).__init__(parent)
11 | self.setupUi(self)
12 | def setupUi(self, settingspage):
13 | self.settingspage = settingspage
14 | self.settingspage.setAttribute(QtCore.Qt.WA_StyledBackground, True)
15 | self.settingspage.setGeometry(QtCore.QRect(60, 0, 1041, 601))
16 | self.settingspage.setStyleSheet("QComboBox::drop-down { border: 0px;}QComboBox::down-arrow { image: url(:/images/down_icon.png); width: 14px; height: 14px;}QComboBox{ padding: 1px 0px 1px 3px;}QLineEdit:focus { border: none; outline: none;}")
17 | self.settings_card = QtWidgets.QWidget(self.settingspage)
18 | self.settings_card.setGeometry(QtCore.QRect(30, 70, 471, 501))
19 | font = QtGui.QFont()
20 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
21 | font.setFamily("Arial")
22 | self.settings_card.setFont(font)
23 | self.settings_card.setStyleSheet("background-color: #232323;border-radius: 20px;border: 1px solid #2e2d2d;")
24 | self.webhook_edit = QtWidgets.QLineEdit(self.settings_card)
25 | self.webhook_edit.setGeometry(QtCore.QRect(30, 50, 411, 21))
26 | self.webhook_edit.setFont(font)
27 | self.webhook_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
28 | self.webhook_edit.setPlaceholderText("Webhook Link")
29 | self.webhook_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
30 | self.webhook_header = QtWidgets.QLabel(self.settings_card)
31 | self.webhook_header.setGeometry(QtCore.QRect(20, 10, 101, 31))
32 | font = QtGui.QFont()
33 | font.setFamily("Arial")
34 | font.setPointSize(18) if platform.system() == "Darwin" else font.setPointSize(18*.75)
35 | font.setWeight(50)
36 | self.webhook_header.setFont(font)
37 | self.webhook_header.setStyleSheet("color: rgb(212, 214, 214);border: none;")
38 | self.webhook_header.setText("Webhook")
39 | self.savesettings_btn = QtWidgets.QPushButton(self.settings_card)
40 | self.savesettings_btn.setGeometry(QtCore.QRect(190, 450, 86, 32))
41 | font = QtGui.QFont()
42 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
43 | font.setFamily("Arial")
44 | self.savesettings_btn.setFont(font)
45 | self.savesettings_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
46 | self.savesettings_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border-radius: 10px;border: 1px solid #2e2d2d;")
47 | self.savesettings_btn.setText("Save")
48 | self.savesettings_btn.clicked.connect(self.save_settings)
49 | self.browser_checkbox = QtWidgets.QCheckBox(self.settings_card)
50 | self.browser_checkbox.setGeometry(QtCore.QRect(30, 90, 111, 20))
51 | self.browser_checkbox.setStyleSheet("color: #FFFFFF;border: none;")
52 | self.browser_checkbox.setText("Browser Opened")
53 | self.order_checkbox = QtWidgets.QCheckBox(self.settings_card)
54 | self.order_checkbox.setGeometry(QtCore.QRect(30, 120, 221, 20))
55 | self.order_checkbox.setStyleSheet("color: #FFFFFF;border: none;")
56 | self.order_checkbox.setText("Order Placed")
57 | self.paymentfailed_checkbox = QtWidgets.QCheckBox(self.settings_card)
58 | self.paymentfailed_checkbox.setGeometry(QtCore.QRect(30, 150, 121, 20))
59 | self.paymentfailed_checkbox.setStyleSheet("color: #FFFFFF;border: none;")
60 | self.paymentfailed_checkbox.setText("Payment Failed")
61 | self.general_header = QtWidgets.QLabel(self.settings_card)
62 | self.general_header.setGeometry(QtCore.QRect(20, 180, 101, 31))
63 | font = QtGui.QFont()
64 | font.setFamily("Arial")
65 | font.setPointSize(18) if platform.system() == "Darwin" else font.setPointSize(18*.75)
66 | font.setWeight(50)
67 | self.general_header.setFont(font)
68 | self.general_header.setStyleSheet("color: rgb(212, 214, 214);border: none;")
69 | self.general_header.setText("General")
70 | self.onfailed_checkbox = QtWidgets.QCheckBox(self.settings_card)
71 | self.onfailed_checkbox.setGeometry(QtCore.QRect(30, 220, 221, 20))
72 | self.onfailed_checkbox.setStyleSheet("color: #FFFFFF;border: none;")
73 | self.onfailed_checkbox.setText("Open browser on payment failed")
74 | self.buy_one_checkbox = QtWidgets.QCheckBox(self.settings_card)
75 | self.buy_one_checkbox.setGeometry(QtCore.QRect(30, 250, 221, 20))
76 | self.buy_one_checkbox.setStyleSheet("color: #FFFFFF;border: none;")
77 | self.buy_one_checkbox.setText("Stop All after success")
78 | self.proxies_header = QtWidgets.QLabel(self.settingspage)
79 | self.proxies_header.setGeometry(QtCore.QRect(30, 10, 81, 31))
80 | font = QtGui.QFont()
81 | font.setFamily("Arial")
82 | font.setPointSize(22) if platform.system() == "Darwin" else font.setPointSize(22*.75)
83 | font.setWeight(50)
84 | self.proxies_header.setFont(font)
85 | self.proxies_header.setStyleSheet("color: rgb(234, 239, 239);")
86 | self.proxies_header.setText("Settings")
87 | self.set_data()
88 | QtCore.QMetaObject.connectSlotsByName(settingspage)
89 |
90 | def set_data(self):
91 | settings = return_data("./data/settings.json")
92 | self.webhook_edit.setText(settings["webhook"])
93 | if settings["webhookonbrowser"]:
94 | self.browser_checkbox.setChecked(True)
95 | if settings["webhookonorder"]:
96 | self.order_checkbox.setChecked(True)
97 | if settings["webhookonfailed"]:
98 | self.paymentfailed_checkbox.setChecked(True)
99 | if settings["browseronfailed"]:
100 | self.onfailed_checkbox.setChecked(True)
101 | if settings['onlybuyone']:
102 | self.buy_one_checkbox.setChecked(True)
103 | self.update_settings(settings)
104 |
105 | def save_settings(self):
106 | settings = {"webhook":self.webhook_edit.text(),
107 | "webhookonbrowser":self.browser_checkbox.isChecked(),
108 | "webhookonorder":self.order_checkbox.isChecked(),
109 | "webhookonfailed":self.paymentfailed_checkbox.isChecked(),
110 | "browseronfailed":self.onfailed_checkbox.isChecked(),
111 | 'onlybuyone':self.buy_one_checkbox.isChecked()}
112 | write_data("./data/settings.json",settings)
113 | self.update_settings(settings)
114 | QtWidgets.QMessageBox.information(self, "Bird Bot", "Saved Settings")
115 |
116 | def update_settings(self,settings_data):
117 | global webhook, webhook_on_browser, webhook_on_order, webhook_on_failed, browser_on_failed
118 | settings.webhook, settings.webhook_on_browser, settings.webhook_on_order, settings.webhook_on_failed, settings.browser_on_failed, settings.buy_one = settings_data["webhook"], settings_data["webhookonbrowser"], settings_data["webhookonorder"], settings_data["webhookonfailed"], settings_data["browseronfailed"], settings_data['onlybuyone']
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/pages/proxiespage.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import QtCore, QtGui, QtWidgets
2 | from utils import return_data,write_data
3 | import sys,platform
4 | def no_abort(a, b, c):
5 | sys.__excepthook__(a, b, c)
6 | sys.excepthook = no_abort
7 |
8 | class ProxiesPage(QtWidgets.QWidget):
9 | def __init__(self,parent=None):
10 | super(ProxiesPage, self).__init__(parent)
11 | self.setupUi(self)
12 | def setupUi(self, proxiespage):
13 | self.proxiespage = proxiespage
14 | self.proxiespage.setAttribute(QtCore.Qt.WA_StyledBackground, True)
15 | self.proxiespage.setGeometry(QtCore.QRect(60, 0, 1041, 601))
16 | self.proxiespage.setStyleSheet("QComboBox::drop-down { border: 0px;}QComboBox::down-arrow { image: url(:/images/down_icon.png); width: 14px; height: 14px;}QComboBox{ padding: 1px 0px 1px 3px;}QLineEdit:focus { border: none; outline: none;}")
17 | self.proxies_card = QtWidgets.QWidget(self.proxiespage)
18 | self.proxies_card.setGeometry(QtCore.QRect(30, 70, 981, 501))
19 | font = QtGui.QFont()
20 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
21 | font.setFamily("Arial")
22 | self.proxies_card.setFont(font)
23 | self.proxies_card.setStyleSheet("background-color: #232323;border-radius: 20px;border: 1px solid #2e2d2d;")
24 | self.listname_edit = QtWidgets.QLineEdit(self.proxies_card)
25 | self.listname_edit.setGeometry(QtCore.QRect(20, 50, 161, 21))
26 | self.listname_edit.setFont(font)
27 | self.listname_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
28 | self.listname_edit.setPlaceholderText("List Name")
29 | self.listname_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
30 | self.editproxies_header = QtWidgets.QLabel(self.proxies_card)
31 | self.editproxies_header.setGeometry(QtCore.QRect(20, 10, 101, 31))
32 | font = QtGui.QFont()
33 | font.setFamily("Arial")
34 | font.setPointSize(18) if platform.system() == "Darwin" else font.setPointSize(18*.75)
35 | font.setWeight(50)
36 | self.editproxies_header.setFont(font)
37 | self.editproxies_header.setStyleSheet("color: rgb(212, 214, 214);border: none;")
38 | self.editproxies_header.setText("Edit Proxies")
39 | self.loadlist_box = QtWidgets.QComboBox(self.proxies_card)
40 | self.loadlist_box.setGeometry(QtCore.QRect(210, 50, 161, 21))
41 | font = QtGui.QFont()
42 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
43 | font.setFamily("Arial")
44 | self.loadlist_box.setFont(font)
45 | self.loadlist_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
46 | self.loadlist_box.addItem("Load List")
47 | self.loadlist_box.currentTextChanged.connect(self.load_proxies)
48 | self.saveproxies_btn = QtWidgets.QPushButton(self.proxies_card)
49 | self.saveproxies_btn.setGeometry(QtCore.QRect(400, 450, 86, 32))
50 | self.saveproxies_btn.setFont(font)
51 | self.saveproxies_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
52 | self.saveproxies_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border-radius: 10px;border: 1px solid #2e2d2d;")
53 | self.saveproxies_btn.setText("Save")
54 | self.saveproxies_btn.clicked.connect(self.save_proxies)
55 | self.proxies_edit = QtWidgets.QTextEdit(self.proxies_card)
56 | self.proxies_edit.setGeometry(QtCore.QRect(20, 90, 941, 341))
57 | self.proxies_edit.setFont(font)
58 | self.proxies_edit.setStyleSheet("color: #FFFFFF;padding: 10px;")
59 | self.proxies_edit.setPlaceholderText("ip:port or ip:port:user:pass")
60 | self.proxies_edit.setAcceptRichText(False)
61 | self.deleteproxies_btn = QtWidgets.QPushButton(self.proxies_card)
62 | self.deleteproxies_btn.setGeometry(QtCore.QRect(500, 450, 86, 32))
63 | self.deleteproxies_btn.setFont(font)
64 | self.deleteproxies_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
65 | self.deleteproxies_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border-radius: 10px;border: 1px solid #2e2d2d;")
66 | self.deleteproxies_btn.setText("Delete")
67 | self.deleteproxies_btn.clicked.connect(self.delete_proxies)
68 | self.proxies_header = QtWidgets.QLabel(self.proxiespage)
69 | self.proxies_header.setGeometry(QtCore.QRect(30, 10, 81, 31))
70 | font = QtGui.QFont()
71 | font.setFamily("Arial")
72 | font.setPointSize(22) if platform.system() == "Darwin" else font.setPointSize(22*.75)
73 | font.setWeight(50)
74 | self.proxies_header.setFont(font)
75 | self.proxies_header.setStyleSheet("color: rgb(234, 239, 239);")
76 | self.proxies_header.setText("Proxies")
77 | self.set_data()
78 | QtCore.QMetaObject.connectSlotsByName(proxiespage)
79 |
80 | def set_data(self):
81 | proxies = return_data("./data/proxies.json")
82 | for proxies_list in proxies:
83 | list_name = proxies_list["list_name"]
84 | self.loadlist_box.addItem(list_name)
85 | self.parent().parent().createdialog.proxies_box.addItem(list_name)
86 |
87 | def load_proxies(self):
88 | list_name = self.loadlist_box.currentText()
89 | if list_name !="Load Proxies":
90 | proxies = return_data("./data/proxies.json")
91 | for proxies_list in proxies:
92 | if proxies_list["list_name"] == list_name:
93 | self.listname_edit.setText(list_name)
94 | self.proxies_edit.setText(proxies_list["proxies"])
95 |
96 | def save_proxies(self):
97 | list_name = self.listname_edit.text()
98 | proxies = self.proxies_edit.toPlainText()
99 | if proxies != "" and list_name != "":
100 | for item in proxies.splitlines():
101 | if ":" not in item or item == "":
102 | QtWidgets.QMessageBox.critical(self, "Bird Bot", "Incorrect Proxies")
103 | return
104 | proxies_data = {
105 | "list_name": list_name,
106 | "proxies": self.proxies_edit.toPlainText()
107 | }
108 | proxies = return_data("./data/proxies.json")
109 | for p in proxies:
110 | if p["list_name"] == list_name:
111 | proxies.remove(p)
112 | break
113 | proxies.append(proxies_data)
114 | write_data("./data/proxies.json",proxies)
115 | if self.loadlist_box.findText(list_name) == -1:
116 | self.loadlist_box.addItem(list_name)
117 | self.parent().parent().createdialog.proxies_box.addItem(list_name)
118 | QtWidgets.QMessageBox.information(self, "Bird Bot", "Saved Proxies")
119 | else:
120 | QtWidgets.QMessageBox.critical(self, "Bird Bot", "Missing Fields")
121 |
122 | def delete_proxies(self):
123 | list_name = self.listname_edit.text()
124 | proxies = return_data("./data/proxies.json")
125 | for p in proxies:
126 | if p["list_name"] == list_name:
127 | proxies.remove(p)
128 | break
129 | write_data("./data/proxies.json",proxies)
130 | self.loadlist_box.removeItem(self.loadlist_box.findText(list_name))
131 | self.parent().parent().createdialog.proxies_box.removeItem(self.parent().parent().createdialog.proxies_box.findText(list_name))
132 | self.loadlist_box.setCurrentIndex(0)
133 | self.listname_edit.setText("")
134 | self.proxies_edit.setText("")
135 | QtWidgets.QMessageBox.information(self, "Bird Bot", "Deleted Proxy List")
136 |
137 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import QtCore, QtGui, QtWidgets
2 | from pages.homepage import HomePage,TaskTab
3 | from pages.createdialog import CreateDialog
4 | from pages.profilespage import ProfilesPage
5 | from pages.proxiespage import ProxiesPage
6 | from pages.settingspage import SettingsPage
7 | import images.images, sys, os
8 | def no_abort(a, b, c):
9 | sys.__excepthook__(a, b, c)
10 | sys.excepthook = no_abort
11 | class MainWindow(QtWidgets.QMainWindow):
12 | def __init__(self, parent=None):
13 | super(MainWindow, self).__init__(parent=parent)
14 | self.setupUi(self)
15 | self.show()
16 | def setupUi(self, MainWindow):
17 | MainWindow.setFixedSize(1109, 600)
18 | MainWindow.setStyleSheet("background-color: #1E1E1E;")
19 | MainWindow.setWindowTitle("Bird Bot")
20 | self.centralwidget = QtWidgets.QWidget(MainWindow)
21 | self.centralwidget.setStyleSheet("QMessageBox QLabel { color: #FFFFFF; }QMessageBox QPushButton { background-color: #5D43FB;color: #FFFFFF;}")
22 | self.sidebar = QtWidgets.QWidget(self.centralwidget)
23 | self.sidebar.setGeometry(QtCore.QRect(0, 0, 61, 601))
24 | self.sidebar.setStyleSheet("background-color: #232323;border-right: 1px solid #2e2d2d;")
25 | self.home_tab = QtWidgets.QWidget(self.sidebar)
26 | self.home_tab.setGeometry(QtCore.QRect(0, 85, 60, 45))
27 | self.home_tab.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
28 | self.home_tab.setStyleSheet("background-color: #272342;border: none;")
29 | self.home_active_tab = QtWidgets.QWidget(self.home_tab)
30 | self.home_active_tab.setGeometry(QtCore.QRect(0, 0, 4, 45))
31 | self.home_active_tab.setStyleSheet("background-color: #5D43FB;border: none;")
32 | self.home_active_tab.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
33 | self.home_icon = QtWidgets.QLabel(self.home_tab)
34 | self.home_icon.setGeometry(QtCore.QRect(21, 13, 20, 20))
35 | self.home_icon.setStyleSheet("border: none;")
36 | self.home_icon.setText("")
37 | self.home_icon.setPixmap(QtGui.QPixmap(":/images/home_alt.png"))
38 | self.home_icon.setScaledContents(True)
39 | self.home_icon.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
40 | self.profiles_tab = QtWidgets.QWidget(self.sidebar)
41 | self.profiles_tab.setGeometry(QtCore.QRect(0, 130, 60, 45))
42 | self.profiles_tab.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
43 | self.profiles_tab.setStyleSheet("background-color: transparent;border: none;")
44 | self.profiles_active_tab = QtWidgets.QWidget(self.profiles_tab)
45 | self.profiles_active_tab.setGeometry(QtCore.QRect(0, 0, 4, 45))
46 | self.profiles_active_tab.setStyleSheet("background-color: transparent;border: none;")
47 | self.profiles_active_tab.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
48 | self.profiles_icon = QtWidgets.QLabel(self.profiles_tab)
49 | self.profiles_icon.setGeometry(QtCore.QRect(21, 13, 20, 20))
50 | self.profiles_icon.setStyleSheet("border: none;")
51 | self.profiles_icon.setText("")
52 | self.profiles_icon.setPixmap(QtGui.QPixmap(":/images/profiles.png"))
53 | self.profiles_icon.setScaledContents(True)
54 | self.profiles_icon.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
55 | self.proxies_tab = QtWidgets.QWidget(self.sidebar)
56 | self.proxies_tab.setGeometry(QtCore.QRect(0, 175, 60, 45))
57 | self.proxies_tab.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
58 | self.proxies_tab.setStyleSheet("background-color: transparent;border: none;")
59 | self.proxies_active_tab = QtWidgets.QWidget(self.proxies_tab)
60 | self.proxies_active_tab.setGeometry(QtCore.QRect(0, 0, 4, 45))
61 | self.proxies_active_tab.setStyleSheet("background-color: transparent;border: none;")
62 | self.proxies_icon = QtWidgets.QLabel(self.proxies_tab)
63 | self.proxies_icon.setGeometry(QtCore.QRect(21, 13, 20, 20))
64 | self.proxies_icon.setStyleSheet("border: none;")
65 | self.proxies_icon.setPixmap(QtGui.QPixmap(":/images/proxies.png"))
66 | self.proxies_icon.setScaledContents(True)
67 | self.settings_tab = QtWidgets.QWidget(self.sidebar)
68 | self.settings_tab.setGeometry(QtCore.QRect(0, 220, 60, 45))
69 | self.settings_tab.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
70 | self.settings_tab.setStyleSheet("background-color: transparent;border: none;")
71 | self.settings_active_tab = QtWidgets.QWidget(self.settings_tab)
72 | self.settings_active_tab.setGeometry(QtCore.QRect(0, 0, 4, 45))
73 | self.settings_active_tab.setStyleSheet("background-color: transparent;border: none;")
74 | self.settings_icon = QtWidgets.QLabel(self.settings_tab)
75 | self.settings_icon.setGeometry(QtCore.QRect(21, 13, 20, 20))
76 | self.settings_icon.setStyleSheet("border: none;")
77 | self.settings_icon.setPixmap(QtGui.QPixmap(":/images/settings.png"))
78 | self.settings_icon.setScaledContents(True)
79 | self.logo = QtWidgets.QLabel(self.sidebar)
80 | self.logo.setGeometry(QtCore.QRect(10, 23, 41, 41))
81 | self.logo.setStyleSheet("border: none;")
82 | self.logo.setText("")
83 | self.logo.setPixmap(QtGui.QPixmap(":/images/birdbot.png"))
84 | self.logo.setScaledContents(True)
85 | self.homepage = HomePage(self.centralwidget)
86 | self.createdialog = CreateDialog(self)
87 | self.createdialog.addtask_btn.clicked.connect(self.create_task)
88 | self.createdialog.setWindowIcon(QtGui.QIcon("images/birdbot.png"))
89 | self.createdialog.hide()
90 | self.profilespage = ProfilesPage(self.centralwidget)
91 | self.profilespage.hide()
92 | self.proxiespage = ProxiesPage(self.centralwidget)
93 | self.proxiespage.hide()
94 | self.settingspage = SettingsPage(self.centralwidget)
95 | self.settingspage.hide()
96 | MainWindow.setCentralWidget(self.centralwidget)
97 | QtCore.QMetaObject.connectSlotsByName(MainWindow)
98 | self.set_functions()
99 | def set_functions(self):
100 | self.current_page = "home"
101 | self.home_tab.mousePressEvent = lambda event: self.change_page(event,"home")
102 | self.profiles_tab.mousePressEvent = lambda event: self.change_page(event,"profiles")
103 | self.proxies_tab.mousePressEvent = lambda event: self.change_page(event,"proxies")
104 | self.settings_tab.mousePressEvent = lambda event: self.change_page(event,"settings")
105 | self.homepage.newtask_btn.clicked.connect(self.createdialog.show)
106 |
107 | def change_page(self,event,current_page):
108 | eval('self.{}_active_tab.setStyleSheet("background-color: transparent;border: none;")'.format(self.current_page))
109 | eval('self.{}_icon.setPixmap(QtGui.QPixmap(":/images/{}.png"))'.format(self.current_page,self.current_page))
110 | eval('self.{}_tab.setStyleSheet("background-color: transparent;border: none;")'.format(self.current_page))
111 | eval("self.{}page.hide()".format(self.current_page))
112 | self.current_page = current_page
113 | eval('self.{}_active_tab.setStyleSheet("background-color: #5D43FB;border: none;")'.format(self.current_page))
114 | eval('self.{}_icon.setPixmap(QtGui.QPixmap(":/images/{}_alt.png"))'.format(self.current_page,self.current_page))
115 | eval('self.{}_tab.setStyleSheet("background-color: #272342;border: none;")'.format(self.current_page))
116 | eval("self.{}page.show()".format(self.current_page))
117 |
118 | def create_task(self):
119 | site = self.createdialog.site_box.currentText()
120 | product = self.createdialog.input_edit.text()
121 | profile = self.createdialog.profile_box.currentText()
122 | proxies = self.createdialog.proxies_box.currentText()
123 | monitor_delay = self.createdialog.monitor_edit.text()
124 | error_delay = self.createdialog.error_edit.text()
125 | max_price = self.createdialog.price_edit.text() if self.createdialog.maxprice_checkbox.isChecked() else ""
126 | if site != "Site" and product != "" and profile != "Profile" and monitor_delay != "" and error_delay != "":
127 | for i in range(self.createdialog.taskcount_spinbox.value()):
128 | self.homepage.verticalLayout.takeAt(self.homepage.verticalLayout.count()-1)
129 | tab = TaskTab(
130 | site,
131 | product,
132 | profile,
133 | proxies,
134 | monitor_delay,
135 | error_delay,
136 | max_price,
137 | self.homepage.stop_all_tasks,
138 | self.homepage.scrollAreaWidgetContents)
139 | self.homepage.verticalLayout.addWidget(tab)
140 | spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
141 | self.homepage.verticalLayout.addItem(spacerItem)
142 |
143 | #(.*)
144 | if __name__ == "__main__":
145 | ui_app = QtWidgets.QApplication(sys.argv)
146 | ui = MainWindow()
147 | ui.setWindowIcon(QtGui.QIcon("images/birdbot.png"))
148 | os._exit(ui_app.exec_())
149 |
--------------------------------------------------------------------------------
/encrypt.js:
--------------------------------------------------------------------------------
1 | var n = {};
2 | n.base10 = "0123456789", n.base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", n.luhn = function (e) {
3 | for (var t = e.length - 1, n = 0; t >= 0;) n += parseInt(e.substr(t, 1), 10), t -= 2;
4 | for (t = e.length - 2; t >= 0;) {
5 | var r = 2 * parseInt(e.substr(t, 1), 10);
6 | n += r < 10 ? r : r - 9, t -= 2
7 | }
8 | return n % 10
9 | }, n.fixluhn = function (e, t, r) {
10 | var a = n.luhn(e);
11 | return a < r ? a += 10 - r : a -= r, 0 != a ? (a = (e.length - t) % 2 != 0 ? 10 - a : a % 2 == 0 ? 5 - a / 2 : (9 - a) / 2 + 5, e.substr(0, t) + a + e.substr(t + 1)) : e
12 | }, n.distill = function (e) {
13 | for (var t = "", r = 0; r < e.length; ++r) n.base10.indexOf(e.charAt(r)) >= 0 && (t += e.substr(r, 1));
14 | return t
15 | }, n.reformat = function (e, t) {
16 | for (var r = "", a = 0, i = 0; i < t.length; ++i) a < e.length && n.base10.indexOf(t.charAt(i)) >= 0 ? (r += e.substr(a, 1), ++a) : r += t.substr(i, 1);
17 | return r
18 | }, n.integrity = function (e, t, n) {
19 | var o = String.fromCharCode(0) + String.fromCharCode(t.length) + t + String.fromCharCode(0) + String.fromCharCode(n.length) + n,
20 | c = a.HexToWords(e);
21 | c[3] ^= 1;
22 | var u = new r.cipher.aes(c),
23 | s = i.compute(u, o);
24 | return a.WordToHex(s[0]) + a.WordToHex(s[1])
25 | }
26 | var r = {
27 | cipher: {},
28 | hash: {},
29 | mode: {},
30 | misc: {},
31 | codec: {},
32 | exception: {
33 | corrupt: function (e) {
34 | this.toString = function () {
35 | return "CORRUPT: " + this.message
36 | }, this.message = e
37 | },
38 | invalid: function (e) {
39 | this.toString = function () {
40 | return "INVALID: " + this.message
41 | }, this.message = e
42 | },
43 | bug: function (e) {
44 | this.toString = function () {
45 | return "BUG: " + this.message
46 | }, this.message = e
47 | }
48 | }
49 | };
50 | r.cipher.aes = function (e) {
51 | this._tables[0][0][0] || this._precompute();
52 | var t, n, a, i, o, c = this._tables[0][4],
53 | u = this._tables[1],
54 | s = e.length,
55 | d = 1;
56 | if (4 !== s && 6 !== s && 8 !== s) throw new r.exception.invalid("invalid aes key size");
57 | for (this._key = [i = e.slice(0), o = []], t = s; t < 4 * s + 28; t++) a = i[t - 1], (t % s == 0 || 8 === s && t % s == 4) && (a = c[a >>> 24] << 24 ^ c[a >> 16 & 255] << 16 ^ c[a >> 8 & 255] << 8 ^ c[255 & a], t % s == 0 && (a = a << 8 ^ a >>> 24 ^ d << 24, d = d << 1 ^ 283 * (d >> 7))), i[t] = i[t - s] ^ a;
58 | for (n = 0; t; n++, t--) a = i[3 & n ? t : t - 4], o[n] = t <= 4 || n < 4 ? a : u[0][c[a >>> 24]] ^ u[1][c[a >> 16 & 255]] ^ u[2][c[a >> 8 & 255]] ^ u[3][c[255 & a]]
59 | }, r.cipher.aes.prototype = {
60 | encrypt: function (e) {
61 | return this._crypt(e, 0)
62 | },
63 | decrypt: function (e) {
64 | return this._crypt(e, 1)
65 | },
66 | _tables: [
67 | [
68 | [],
69 | [],
70 | [],
71 | [],
72 | []
73 | ],
74 | [
75 | [],
76 | [],
77 | [],
78 | [],
79 | []
80 | ]
81 | ],
82 | _precompute: function () {
83 | var e, t, n, r, a, i, o, c, u = this._tables[0],
84 | s = this._tables[1],
85 | d = u[4],
86 | l = s[4],
87 | f = [],
88 | p = [];
89 | for (e = 0; e < 256; e++) p[(f[e] = e << 1 ^ 283 * (e >> 7)) ^ e] = e;
90 | for (t = n = 0; !d[t]; t ^= 0 == r ? 1 : r, n = 0 == p[n] ? 1 : p[n])
91 | for (i = (i = n ^ n << 1 ^ n << 2 ^ n << 3 ^ n << 4) >> 8 ^ 255 & i ^ 99, d[t] = i, l[i] = t, c = 16843009 * f[a = f[r = f[t]]] ^ 65537 * a ^ 257 * r ^ 16843008 * t, o = 257 * f[i] ^ 16843008 * i, e = 0; e < 4; e++) u[e][t] = o = o << 24 ^ o >>> 8, s[e][i] = c = c << 24 ^ c >>> 8;
92 | for (e = 0; e < 5; e++) u[e] = u[e].slice(0), s[e] = s[e].slice(0)
93 | },
94 | _crypt: function (e, t) {
95 | if (4 !== e.length) throw new r.exception.invalid("invalid aes block size");
96 | var n, a, i, o, c = this._key[t],
97 | u = e[0] ^ c[0],
98 | s = e[t ? 3 : 1] ^ c[1],
99 | d = e[2] ^ c[2],
100 | l = e[t ? 1 : 3] ^ c[3],
101 | f = c.length / 4 - 2,
102 | p = 4,
103 | m = [0, 0, 0, 0],
104 | h = this._tables[t],
105 | b = h[0],
106 | v = h[1],
107 | y = h[2],
108 | E = h[3],
109 | g = h[4];
110 | for (o = 0; o < f; o++) n = b[u >>> 24] ^ v[s >> 16 & 255] ^ y[d >> 8 & 255] ^ E[255 & l] ^ c[p], a = b[s >>> 24] ^ v[d >> 16 & 255] ^ y[l >> 8 & 255] ^ E[255 & u] ^ c[p + 1], i = b[d >>> 24] ^ v[l >> 16 & 255] ^ y[u >> 8 & 255] ^ E[255 & s] ^ c[p + 2], l = b[l >>> 24] ^ v[u >> 16 & 255] ^ y[s >> 8 & 255] ^ E[255 & d] ^ c[p + 3], p += 4, u = n, s = a, d = i;
111 | for (o = 0; o < 4; o++) m[t ? 3 & -o : o] = g[u >>> 24] << 24 ^ g[s >> 16 & 255] << 16 ^ g[d >> 8 & 255] << 8 ^ g[255 & l] ^ c[p++], n = u, u = s, s = d, d = l, l = n;
112 | return m
113 | }
114 | };
115 | var a = {
116 | HexToKey: function (e) {
117 | return new r.cipher.aes(a.HexToWords(e))
118 | },
119 | HexToWords: function (e) {
120 | var t = new Array(4);
121 | if (32 != e.length) return null;
122 | for (var n = 0; n < 4; n++) t[n] = parseInt(e.substr(8 * n, 8), 16);
123 | return t
124 | },
125 | Hex: "0123456789abcdef",
126 | WordToHex: function (e) {
127 | for (var t = 32, n = ""; t > 0;) t -= 4, n += a.Hex.substr(e >>> t & 15, 1);
128 | return n
129 | }
130 | },
131 | i = {};
132 | i.MSBnotZero = function (e) {
133 | return 2147483647 != (2147483647 | e)
134 | }, i.leftShift = function (e) {
135 | e[0] = (2147483647 & e[0]) << 1 | e[1] >>> 31, e[1] = (2147483647 & e[1]) << 1 | e[2] >>> 31, e[2] = (2147483647 & e[2]) << 1 | e[3] >>> 31, e[3] = (2147483647 & e[3]) << 1
136 | }, i.const_Rb = 135, i.compute = function (e, t) {
137 | var n = [0, 0, 0, 0],
138 | r = e.encrypt(n),
139 | a = r[0];
140 | i.leftShift(r), i.MSBnotZero(a) && (r[3] ^= i.const_Rb);
141 | for (var o = 0; o < t.length;) n[o >> 2 & 3] ^= (255 & t.charCodeAt(o)) << 8 * (3 - (3 & o)), 0 == (15 & ++o) && o < t.length && (n = e.encrypt(n));
142 | return 0 != o && 0 == (15 & o) || (a = r[0], i.leftShift(r), i.MSBnotZero(a) && (r[3] ^= i.const_Rb), n[o >> 2 & 3] ^= 128 << 8 * (3 - (3 & o))), n[0] ^= r[0], n[1] ^= r[1], n[2] ^= r[2], n[3] ^= r[3], e.encrypt(n)
143 | };
144 | var o = {
145 | alphabet: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"],
146 | precompF: function (e, t, n, r) {
147 | var a = new Array(4),
148 | i = n.length;
149 | return a[0] = 16908544 | r >> 16 & 255, a[1] = (r >> 8 & 255) << 24 | (255 & r) << 16 | 2560 | 255 & Math.floor(t / 2), a[2] = t, a[3] = i, e.encrypt(a)
150 | },
151 | precompb: function (e, t) {
152 | for (var n = Math.ceil(t / 2), r = 0, a = 1; n > 0;) --n, (a *= e) >= 256 && (a /= 256, ++r);
153 | return a > 1 && ++r, r
154 | },
155 | bnMultiply: function (e, t, n) {
156 | var r, a = 0;
157 | for (r = e.length - 1; r >= 0; --r) {
158 | var i = e[r] * n + a;
159 | e[r] = i % t, a = (i - e[r]) / t
160 | }
161 | },
162 | bnAdd: function (e, t, n) {
163 | for (var r = e.length - 1, a = n; r >= 0 && a > 0;) {
164 | var i = e[r] + a;
165 | e[r] = i % t, a = (i - e[r]) / t, --r
166 | }
167 | },
168 | convertRadix: function (e, t, n, r, a) {
169 | var i, c = new Array(r);
170 | for (i = 0; i < r; ++i) c[i] = 0;
171 | for (var u = 0; u < t; ++u) o.bnMultiply(c, a, n), o.bnAdd(c, a, e[u]);
172 | return c
173 | },
174 | cbcmacq: function (e, t, n, r) {
175 | for (var a = new Array(4), i = 0; i < 4; ++i) a[i] = e[i];
176 | for (var o = 0; 4 * o < n;) {
177 | for (i = 0; i < 4; ++i) a[i] = a[i] ^ (t[4 * (o + i)] << 24 | t[4 * (o + i) + 1] << 16 | t[4 * (o + i) + 2] << 8 | t[4 * (o + i) + 3]);
178 | a = r.encrypt(a), o += 4
179 | }
180 | return a
181 | },
182 | F: function (e, t, n, r, a, i, c, u, s) {
183 | var d = Math.ceil(s / 4) + 1,
184 | l = n.length + s + 1 & 15;
185 | l > 0 && (l = 16 - l);
186 | var f, p = new Array(n.length + l + s + 1);
187 | for (f = 0; f < n.length; f++) p[f] = n.charCodeAt(f);
188 | for (; f < l + n.length; f++) p[f] = 0;
189 | p[p.length - s - 1] = t;
190 | for (var m = o.convertRadix(r, a, u, s, 256), h = 0; h < s; h++) p[p.length - s + h] = m[h];
191 | var b, v = o.cbcmacq(c, p, p.length, e),
192 | y = v,
193 | E = new Array(2 * d);
194 | for (f = 0; f < d; ++f) f > 0 && 0 == (3 & f) && (b = f >> 2 & 255, b |= b << 8 | b << 16 | b << 24, y = e.encrypt([v[0] ^ b, v[1] ^ b, v[2] ^ b, v[3] ^ b])), E[2 * f] = y[3 & f] >>> 16, E[2 * f + 1] = 65535 & y[3 & f];
195 | return o.convertRadix(E, 2 * d, 65536, i, u)
196 | },
197 | DigitToVal: function (e, t, n) {
198 | var r = new Array(t);
199 | if (256 == n) {
200 | for (var a = 0; a < t; a++) r[a] = e.charCodeAt(a);
201 | return r
202 | }
203 | for (var i = 0; i < t; i++) {
204 | var o = parseInt(e.charAt(i), n);
205 | if (NaN == o || !(o < n)) return "";
206 | r[i] = o
207 | }
208 | return r
209 | },
210 | ValToDigit: function (e, t) {
211 | var n, r = "";
212 | if (256 == t)
213 | for (n = 0; n < e.length; n++) r += String.fromCharCode(e[n]);
214 | else
215 | for (n = 0; n < e.length; n++) r += o.alphabet[e[n]];
216 | return r
217 | },
218 | encryptWithCipher: function (e, t, n, r) {
219 | var a = e.length,
220 | i = Math.floor(a / 2),
221 | c = o.precompF(n, a, t, r),
222 | u = o.precompb(r, a),
223 | s = o.DigitToVal(e, i, r),
224 | d = o.DigitToVal(e.substr(i), a - i, r);
225 | if ("" == s || "" == d) return "";
226 | for (var l = 0; l < 5; l++) {
227 | var f, p = o.F(n, 2 * l, t, d, d.length, s.length, c, r, u);
228 | f = 0;
229 | for (var m = s.length - 1; m >= 0; --m) {
230 | (h = s[m] + p[m] + f) < r ? (s[m] = h, f = 0) : (s[m] = h - r, f = 1)
231 | }
232 | p = o.F(n, 2 * l + 1, t, s, s.length, d.length, c, r, u);
233 | f = 0;
234 | for (m = d.length - 1; m >= 0; --m) {
235 | var h;
236 | (h = d[m] + p[m] + f) < r ? (d[m] = h, f = 0) : (d[m] = h - r, f = 1)
237 | }
238 | }
239 | return o.ValToDigit(s, r) + o.ValToDigit(d, r)
240 | },
241 | encrypt: function (e, t, n, r) {
242 | var i = a.HexToKey(n);
243 | return null == i ? "" : o.encryptWithCipher(e, t, i, r)
244 | }
245 | }
246 | function encrypt(e,t,PIE_L,PIE_E,PIE_K,PIE_key_id,PIE_phase){
247 | PIE = {L: parseInt(PIE_L), E: parseInt(PIE_E), K: PIE_K, key_id: PIE_key_id, phase: parseInt(PIE_phase)}
248 | var a_var = n.distill(e)
249 | var i_var = n.distill(t)
250 | var c_var = a_var.substr(0, PIE.L) + a_var.substring(a_var.length - PIE.E)
251 | var u_var = n.luhn(a_var)
252 | var s_var = a_var.substring(PIE.L + 1, a_var.length - PIE.E)
253 | var d_var = o.encrypt(s_var + i_var, c_var, PIE.K, 10)
254 | var l_var = a_var.substr(0, PIE.L) + "0" + d_var.substr(0, d_var.length - i_var.length) + a_var.substring(a_var.length - PIE.E)
255 | var f_var = n.reformat(n.fixluhn(l_var, PIE.L, u_var), e)
256 | var p_var = n.reformat(d_var.substring(d_var.length - i_var.length), t)
257 | return [f_var, p_var, n.integrity(PIE.K, f_var, p_var)]
258 | }
--------------------------------------------------------------------------------
/sites/walmart.py:
--------------------------------------------------------------------------------
1 | from sites.walmart_encryption import walmart_encryption as w_e
2 | from utils import send_webhook
3 | import urllib,requests,time,lxml.html,json,sys,settings
4 |
5 | class Walmart:
6 | def __init__(self,task_id,status_signal,image_signal,product,profile,proxy,monitor_delay,error_delay,max_price):
7 | self.task_id,self.status_signal,self.image_signal,self.product,self.profile,self.monitor_delay,self.error_delay,self.max_price = task_id,status_signal,image_signal,product,profile,float(monitor_delay),float(error_delay),max_price
8 | self.session = requests.Session()
9 | if proxy != False:
10 | self.session.proxies.update(proxy)
11 | self.status_signal.emit({"msg":"Starting","status":"normal"})
12 | self.product_image, offer_id = self.monitor()
13 | self.atc(offer_id)
14 | item_id, fulfillment_option, ship_method = self.check_cart_items()
15 | self.submit_shipping_method(item_id, fulfillment_option, ship_method)
16 | self.submit_shipping_address()
17 | card_data,PIE_key_id,PIE_phase = self.get_PIE()
18 | pi_hash = self.submit_payment(card_data,PIE_key_id,PIE_phase)
19 | self.submit_billing(pi_hash)
20 | self.submit_order()
21 | def monitor(self):
22 | headers = {
23 | "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
24 | "accept-encoding": "gzip, deflate, br",
25 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
26 | "cache-control": "max-age=0",
27 | "upgrade-insecure-requests": "1",
28 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36"
29 | }
30 | image_found = False
31 | sproduct_image = ""
32 | while True:
33 | self.status_signal.emit({"msg":"Loading Product Page","status":"normal"})
34 | try:
35 | r = self.session.get(self.product,headers=headers)
36 | if r.status_code == 200:
37 | doc = lxml.html.fromstring(r.text)
38 | if not image_found:
39 | product_image = doc.xpath('//meta[@property="og:image"]/@content')[0]
40 | self.image_signal.emit(product_image)
41 | image_found = True
42 | price = float(doc.xpath('//span[@itemprop="price"]/@content')[0])
43 | if "Add to Cart" in r.text:
44 | if self.max_price !="":
45 | if float(self.max_price) < price:
46 | self.status_signal.emit({"msg":"Waiting For Price Restock","status":"normal"})
47 | self.session.cookies.clear()
48 | time.sleep(self.monitor_delay)
49 | continue
50 | offer_id = json.loads(doc.xpath('//script[@id="item"]/text()')[0])["item"]["product"]["buyBox"]["products"][0]["offerId"]
51 | return product_image, offer_id
52 | self.status_signal.emit({"msg":"Waiting For Restock","status":"normal"})
53 | self.session.cookies.clear()
54 | time.sleep(self.monitor_delay)
55 | else:
56 | self.status_signal.emit({"msg":"Product Not Found","status":"normal"})
57 | time.sleep(self.monitor_delay)
58 | except Exception as e:
59 | self.status_signal.emit({"msg":"Error Loading Product Page (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
60 | time.sleep(self.error_delay)
61 |
62 | def atc(self,offer_id):
63 | headers={
64 | "accept": "application/json",
65 | "accept-encoding": "gzip, deflate, br",
66 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
67 | "content-type": "application/json",
68 | "origin": "https://www.walmart.com",
69 | "referer": self.product,
70 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36"
71 | }
72 | body = {"offerId":offer_id,"quantity":1}
73 | while True:
74 | self.status_signal.emit({"msg":"Adding To Cart","status":"normal"})
75 | try:
76 | r = self.session.post("https://www.walmart.com/api/v3/cart/guest/:CID/items",json=body,headers=headers)
77 | if r.status_code == 201 and json.loads(r.text)["checkoutable"] == True:
78 | self.status_signal.emit({"msg":"Added To Cart","status":"carted"})
79 | return
80 | else:
81 | self.status_signal.emit({"msg":"Error Adding To Cart","status":"error"})
82 | time.sleep(self.error_delay)
83 | except Exception as e:
84 | self.status_signal.emit({"msg":"Error Adding To Cart (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
85 | time.sleep(self.error_delay)
86 |
87 | def check_cart_items(self):
88 | headers = {
89 | "accept": "application/json, text/javascript, */*; q=0.01",
90 | "accept-encoding": "gzip, deflate, br",
91 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
92 | "content-type": "application/json",
93 | "origin": "https://www.walmart.com",
94 | "referer": "https://www.walmart.com/checkout/",
95 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36",
96 | "wm_vertical_id": "0"
97 | }
98 | profile = self.profile
99 | body = {"postalCode":profile["shipping_zipcode"],"city":profile["shipping_city"],"state":profile["shipping_state"],"isZipLocated":True,"crt:CRT":"","customerId:CID":"","customerType:type":"","affiliateInfo:com.wm.reflector":""}
100 | while True:
101 | self.status_signal.emit({"msg":"Loading Cart Items","status":"normal"})
102 | try:
103 | r = self.session.post("https://www.walmart.com/api/checkout/v3/contract?page=CHECKOUT_VIEW",json=body,headers=headers)
104 | if r.status_code == 201:
105 | r = json.loads(r.text)["items"][0]
106 | item_id = r["id"]
107 | fulfillment_option = r["fulfillmentSelection"]["fulfillmentOption"]
108 | ship_method = r["fulfillmentSelection"]["shipMethod"]
109 | self.status_signal.emit({"msg":"Loaded Cart Items","status":"normal"})
110 | return item_id, fulfillment_option, ship_method
111 | else:
112 | if json.loads(r.text)["message"] == "Item is no longer in stock.":
113 | self.status_signal.emit({"msg":"Waiting For Restock","status":"normal"})
114 | time.sleep(self.monitor_delay)
115 | else:
116 | self.status_signal.emit({"msg":"Error Loading Cart Items, Got Response: "+str(r.text),"status":"error"})
117 | time.sleep(self.error_delay)
118 | except Exception as e:
119 | self.status_signal.emit({"msg":"Error Loading Cart Items (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
120 | time.sleep(self.error_delay)
121 |
122 | def submit_shipping_method(self, item_id, fulfillment_option, ship_method):
123 | headers = {
124 | "accept": "application/json, text/javascript, */*; q=0.01",
125 | "accept-encoding": "gzip, deflate, br",
126 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
127 | "content-type": "application/json",
128 | "origin": "https://www.walmart.com",
129 | "referer": "https://www.walmart.com/checkout/",
130 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36",
131 | "wm_vertical_id": "0"
132 | }
133 | body = {"groups":[{"fulfillmentOption":fulfillment_option,"itemIds":[item_id],"shipMethod":ship_method}]}
134 | while True:
135 | self.status_signal.emit({"msg":"Submitting Shipping Method","status":"normal"})
136 | try:
137 | r = self.session.post("https://www.walmart.com/api/checkout/v3/contract/:PCID/fulfillment",json=body,headers=headers)
138 | if r.status_code == 200:
139 | try:
140 | r = json.loads(r.text)
141 | self.status_signal.emit({"msg":"Submitted Shipping Method","status":"normal"})
142 | return
143 | except:
144 | pass
145 | self.status_signal.emit({"msg":"Error Submitting Shipping Method","status":"error"})
146 | time.sleep(self.error_delay)
147 | except Exception as e:
148 | self.status_signal.emit({"msg":"Error Submitting Shipping Method (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
149 | time.sleep(self.error_delay)
150 |
151 | def submit_shipping_address(self):
152 | headers = {
153 | "accept": "application/json, text/javascript, */*; q=0.01",
154 | "accept-encoding": "gzip, deflate, br",
155 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
156 | "content-type": "application/json",
157 | "inkiru_precedence": "false",
158 | "origin": "https://www.walmart.com",
159 | "referer": "https://www.walmart.com/checkout/",
160 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36",
161 | "wm_vertical_id": "0"
162 | }
163 | profile = self.profile
164 | body = {
165 | "addressLineOne":profile["shipping_a1"],
166 | "city":profile["shipping_city"],
167 | "firstName":profile["shipping_fname"],
168 | "lastName":profile["shipping_lname"],
169 | "phone":profile["shipping_phone"],
170 | "email":profile["shipping_email"],
171 | "marketingEmailPref":False,
172 | "postalCode":profile["shipping_zipcode"],
173 | "state":profile["shipping_state"],
174 | "countryCode":"USA",
175 | "addressType":"RESIDENTIAL",
176 | "changedFields":[]
177 | }
178 | if profile["shipping_a2"] !="":
179 | body.update({"addressLineTwo":profile["shipping_a2"]})
180 | while True:
181 | self.status_signal.emit({"msg":"Submitting Shipping Address","status":"normal"})
182 | try:
183 | r = self.session.post("https://www.walmart.com/api/checkout/v3/contract/:PCID/shipping-address",json=body,headers=headers)
184 | if r.status_code == 200:
185 | try:
186 | r = json.loads(r.text)
187 | self.status_signal.emit({"msg":"Submitted Shipping Address","status":"normal"})
188 | return
189 | except:
190 | pass
191 | self.status_signal.emit({"msg":"Error Submitting Shipping Address","status":"error"})
192 | time.sleep(self.error_delay)
193 | except Exception as e:
194 | self.status_signal.emit({"msg":"Error Submitting Shipping Address (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
195 | time.sleep(self.error_delay)
196 |
197 | def get_PIE(self):
198 | headers = {
199 | "Accept": "*/*",
200 | "Accept-Encoding": "gzip, deflate, br",
201 | "Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
202 | "Connection": "keep-alive",
203 | "Host": "securedataweb.walmart.com",
204 | "Referer": "https://www.walmart.com/",
205 | "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36"
206 | }
207 | profile = self.profile
208 | while True:
209 | self.status_signal.emit({"msg":"Getting Checkout Data","status":"normal"})
210 | try:
211 | r = self.session.get("https://securedataweb.walmart.com/pie/v1/wmcom_us_vtg_pie/getkey.js?bust="+str(int(time.time())),headers=headers)
212 | if r.status_code == 200:
213 | PIE_L = int(r.text.split("PIE.L = ")[1].split(";")[0])
214 | PIE_E = int(r.text.split("PIE.E = ")[1].split(";")[0])
215 | PIE_K = str(r.text.split('PIE.K = "')[1].split('";')[0])
216 | PIE_key_id = str(r.text.split('PIE.key_id = "')[1].split('";')[0])
217 | PIE_phase = int(r.text.split('PIE.phase = ')[1].split(';')[0])
218 | card_data = w_e.encrypt(profile["card_number"],profile["card_cvv"],PIE_L,PIE_E,PIE_K,PIE_key_id,PIE_phase)
219 | self.status_signal.emit({"msg":"Got Checkout Data","status":"normal"})
220 | return card_data, PIE_key_id, PIE_phase
221 | self.status_signal.emit({"msg":"Error Getting Checkout Data","status":"error"})
222 | time.sleep(self.error_delay)
223 | except Exception as e:
224 | self.status_signal.emit({"msg":"Error Getting Checkout Data (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
225 | time.sleep(self.error_delay)
226 |
227 | def submit_payment(self,card_data,PIE_key_id,PIE_phase):
228 | headers = {
229 | "accept": "application/json",
230 | "accept-encoding": "gzip, deflate, br",
231 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
232 | "content-type": "application/json",
233 | "inkiru_precedence": "false",
234 | "origin": "https://www.walmart.com",
235 | "referer": "https://www.walmart.com/checkout/",
236 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36"
237 | }
238 | profile = self.profile
239 | body = {
240 | "encryptedPan": card_data[0],
241 | "encryptedCvv": card_data[1],
242 | "integrityCheck": card_data[2],
243 | "keyId": PIE_key_id,
244 | "phase": PIE_phase,
245 | "state": profile["billing_state"],
246 | "postalCode": profile["billing_zipcode"],
247 | "addressLineOne": profile["billing_a1"],
248 | "addressLineTwo": profile["billing_a2"],
249 | "city": profile["billing_city"],
250 | "firstName": profile["billing_fname"],
251 | "lastName": profile["billing_lname"],
252 | "expiryMonth": profile["card_month"],
253 | "expiryYear": profile["card_year"],
254 | "phone": profile["billing_phone"],
255 | "cardType": profile["card_type"].upper(),
256 | "isGuest":True
257 | }
258 | while True:
259 | self.status_signal.emit({"msg":"Submitting Payment","status":"normal"})
260 | try:
261 | r = self.session.post("https://www.walmart.com/api/checkout-customer/:CID/credit-card",json=body,headers=headers)
262 | if r.status_code == 200:
263 | pi_hash = json.loads(r.text)["piHash"]
264 | self.status_signal.emit({"msg":"Submitted Payment","status":"normal"})
265 | return pi_hash
266 | self.status_signal.emit({"msg":"Error Submitting Payment","status":"error"})
267 | if self.check_browser():
268 | return
269 | time.sleep(self.error_delay)
270 | except Exception as e:
271 | self.status_signal.emit({"msg":"Error Submitting Payment (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
272 | time.sleep(self.error_delay)
273 |
274 | def submit_billing(self,pi_hash):
275 | headers = {
276 | "accept": "application/json, text/javascript, */*; q=0.01",
277 | "accept-encoding": "gzip, deflate, br",
278 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
279 | "content-type": "application/json",
280 | "inkiru_precedence": "false",
281 | "origin": "https://www.walmart.com",
282 | "referer": "https://www.walmart.com/checkout/",
283 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36",
284 | "wm_vertical_id": "0"
285 | }
286 | profile = self.profile
287 | card_data,PIE_key_id,PIE_phase = self.get_PIE()
288 | body = {
289 | "payments":[{
290 | "paymentType":"CREDITCARD",
291 | "cardType": profile["card_type"].upper(),
292 | "firstName": profile["billing_fname"],
293 | "lastName": profile["billing_lname"],
294 | "addressLineOne": profile["billing_a1"],
295 | "addressLineTwo": profile["billing_a2"],
296 | "city": profile["billing_city"],
297 | "state": profile["billing_state"],
298 | "postalCode": profile["billing_zipcode"],
299 | "expiryMonth": profile["card_month"],
300 | "expiryYear": profile["card_year"],
301 | "email": profile["billing_email"],
302 | "phone": profile["billing_phone"],
303 | "encryptedPan": card_data[0],
304 | "encryptedCvv": card_data[1],
305 | "integrityCheck": card_data[2],
306 | "keyId": PIE_key_id,
307 | "phase": PIE_phase,
308 | "piHash": pi_hash
309 | }]
310 | }
311 | while True:
312 | self.status_signal.emit({"msg":"Submitting Billing","status":"normal"})
313 | try:
314 | r = self.session.post("https://www.walmart.com/api/checkout/v3/contract/:PCID/payment",json=body,headers=headers)
315 | if r.status_code == 200:
316 | try:
317 | r = json.loads(r.text)
318 | self.status_signal.emit({"msg":"Submitted Billing","status":"normal"})
319 | return
320 | except:
321 | pass
322 | self.status_signal.emit({"msg":"Error Submitting Billing","status":"error"})
323 | if self.check_browser():
324 | return
325 | time.sleep(self.error_delay)
326 | except Exception as e:
327 | self.status_signal.emit({"msg":"Error Submitting Billing (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
328 | time.sleep(self.error_delay)
329 |
330 | def submit_order(self):
331 | headers = {
332 | "accept": "application/json, text/javascript, */*; q=0.01",
333 | "accept-encoding": "gzip, deflate, br",
334 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
335 | "content-type": "application/json",
336 | "inkiru_precedence": "false",
337 | "origin": "https://www.walmart.com",
338 | "referer": "https://www.walmart.com/checkout/",
339 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36",
340 | "wm_vertical_id": "0"
341 | }
342 | while True:
343 | self.status_signal.emit({"msg":"Submitting Order","status":"alt"})
344 | try:
345 | r = self.session.put("https://www.walmart.com/api/checkout/v3/contract/:PCID/order",json={},headers=headers)
346 | try:
347 | json.loads(r.text)["order"]
348 | self.status_signal.emit({"msg":"Order Placed","status":"success"})
349 | send_webhook("OP","Walmart",self.profile["profile_name"],self.task_id,self.product_image)
350 | return
351 | except:
352 | self.status_signal.emit({"msg":"Payment Failed","status":"error"})
353 | if self.check_browser():
354 | return
355 | send_webhook("PF","Walmart",self.profile["profile_name"],self.task_id,self.product_image)
356 | return
357 | except Exception as e:
358 | self.status_signal.emit({"msg":"Error Submitting Order (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
359 | time.sleep(self.error_delay)
360 |
361 | def check_browser(self):
362 | if settings.browser_on_failed:
363 | self.status_signal.emit({"msg":"Browser Ready","status":"alt","url":"https://www.walmart.com/checkout/#/payment","cookies":[{"name":cookie.name,"value":cookie.value,"domain":cookie.domain} for cookie in self.session.cookies]})
364 | send_webhook("B","Walmart",self.profile["profile_name"],self.task_id,self.product_image)
365 | return True
366 | return False
--------------------------------------------------------------------------------
/pages/homepage.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import QtCore, QtGui, QtWidgets
2 | from sites.walmart import Walmart
3 | from sites.bestbuy import BestBuy
4 | from pages.createdialog import CreateDialog
5 | from utils import get_profile, get_proxy, BirdLogger, return_data, write_data, open_browser
6 | import urllib.request,sys,platform
7 | import settings
8 | def no_abort(a, b, c):
9 | sys.__excepthook__(a, b, c)
10 | sys.excepthook = no_abort
11 | logger = BirdLogger()
12 | class HomePage(QtWidgets.QWidget):
13 | def __init__(self,parent=None):
14 | super(HomePage, self).__init__(parent)
15 | self.setupUi(self)
16 | self.load_tasks()
17 | def setupUi(self, homepage):
18 | global tasks
19 | self.tasks = []
20 | tasks = self.tasks
21 | self.homepage = homepage
22 | self.homepage.setAttribute(QtCore.Qt.WA_StyledBackground, True)
23 | self.homepage.setGeometry(QtCore.QRect(60, 0, 1041, 601))
24 | self.tasks_card = QtWidgets.QWidget(self.homepage)
25 | self.tasks_card.setGeometry(QtCore.QRect(30, 110, 991, 461))
26 | self.tasks_card.setStyleSheet("background-color: #232323;border-radius: 20px;border: 1px solid #2e2d2d;")
27 | self.scrollArea = QtWidgets.QScrollArea(self.tasks_card)
28 | self.scrollArea.setGeometry(QtCore.QRect(20, 30, 951, 421))
29 | self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
30 | self.scrollArea.setStyleSheet("border:none;")
31 | self.scrollArea.setWidgetResizable(True)
32 | self.scrollAreaWidgetContents = QtWidgets.QWidget()
33 | self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 951, 421))
34 | self.verticalLayout = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
35 | self.verticalLayout.setContentsMargins(0, -1, 0, -1)
36 | self.verticalLayout.setSpacing(2)
37 | spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
38 | self.verticalLayout.addItem(spacerItem)
39 | self.scrollArea.setWidget(self.scrollAreaWidgetContents)
40 | self.image_table_header = QtWidgets.QLabel(self.tasks_card)
41 | self.image_table_header.setGeometry(QtCore.QRect(40, 7, 51, 31))
42 | self.image_table_header.setText("Image")
43 | font = QtGui.QFont()
44 | font.setFamily("Arial")
45 | font.setPointSize(15) if platform.system() == "Darwin" else font.setPointSize(15*.75)
46 | font.setBold(False)
47 | font.setWeight(50)
48 | self.image_table_header.setFont(font)
49 | self.image_table_header.setStyleSheet("color: rgb(234, 239, 239);border: none;")
50 | self.product_table_header = QtWidgets.QLabel(self.tasks_card)
51 | self.product_table_header.setGeometry(QtCore.QRect(240, 7, 61, 31))
52 | self.product_table_header.setFont(font)
53 | self.product_table_header.setStyleSheet("color: rgb(234, 239, 239);border: none;")
54 | self.product_table_header.setText("Product")
55 | self.profile_table_header = QtWidgets.QLabel(self.tasks_card)
56 | self.profile_table_header.setGeometry(QtCore.QRect(590, 7, 61, 31))
57 | self.profile_table_header.setFont(font)
58 | self.profile_table_header.setStyleSheet("color: rgb(234, 239, 239);border: none;")
59 | self.profile_table_header.setText("Profile")
60 | self.status_table_header = QtWidgets.QLabel(self.tasks_card)
61 | self.status_table_header.setGeometry(QtCore.QRect(650, 7, 61, 31))
62 | self.status_table_header.setFont(font)
63 | self.status_table_header.setStyleSheet("color: rgb(234, 239, 239);border: none;")
64 | self.status_table_header.setText("Status")
65 | self.actions_table_header = QtWidgets.QLabel(self.tasks_card)
66 | self.actions_table_header.setGeometry(QtCore.QRect(890, 7, 61, 31))
67 | self.actions_table_header.setFont(font)
68 | self.actions_table_header.setStyleSheet("color: rgb(234, 239, 239);border: none;")
69 | self.actions_table_header.setText("Actions")
70 | self.site_table_header = QtWidgets.QLabel(self.tasks_card)
71 | self.site_table_header.setGeometry(QtCore.QRect(160, 7, 61, 31))
72 | self.site_table_header.setFont(font)
73 | self.site_table_header.setStyleSheet("color: rgb(234, 239, 239);border: none;")
74 | self.site_table_header.setText("Site")
75 | self.id_header = QtWidgets.QLabel(self.tasks_card)
76 | self.id_header.setGeometry(QtCore.QRect(110, 7, 31, 31))
77 | self.id_header.setFont(font)
78 | self.id_header.setStyleSheet("color: rgb(234, 239, 239);border: none;")
79 | self.id_header.setText("ID")
80 | self.tasks_header = QtWidgets.QLabel(self.homepage)
81 | self.tasks_header.setGeometry(QtCore.QRect(30, 10, 61, 31))
82 | self.tasks_header.setText("Tasks")
83 | font = QtGui.QFont()
84 | font.setFamily("Arial")
85 | font.setPointSize(22) if platform.system() == "Darwin" else font.setPointSize(22*.75)
86 | font.setBold(False)
87 | font.setWeight(50)
88 | self.tasks_header.setFont(font)
89 | self.tasks_header.setStyleSheet("color: rgb(234, 239, 239);")
90 | self.checkouts_card = QtWidgets.QWidget(self.homepage)
91 | self.checkouts_card.setGeometry(QtCore.QRect(440, 45, 171, 51))
92 | self.checkouts_card.setStyleSheet("background-color: #232323;border-radius: 10px;border: 1px solid #2e2d2d;")
93 | self.checkouts_label = QtWidgets.QLabel(self.checkouts_card)
94 | self.checkouts_label.setGeometry(QtCore.QRect(78, 10, 81, 31))
95 | font = QtGui.QFont()
96 | font.setFamily("Arial")
97 | font.setPointSize(16) if platform.system() == "Darwin" else font.setPointSize(16*.75)
98 | font.setBold(False)
99 | font.setWeight(50)
100 | self.checkouts_label.setFont(font)
101 | self.checkouts_label.setStyleSheet("color: rgb(234, 239, 239);border: none;")
102 | self.checkouts_label.setText("Checkouts")
103 | self.checkouts_icon = QtWidgets.QLabel(self.checkouts_card)
104 | self.checkouts_icon.setGeometry(QtCore.QRect(10, 10, 31, 31))
105 | self.checkouts_icon.setStyleSheet("border: none;")
106 | self.checkouts_icon.setText("")
107 | self.checkouts_icon.setPixmap(QtGui.QPixmap(":/images/success.png"))
108 | self.checkouts_icon.setScaledContents(True)
109 | global checkouts_count
110 | self.checkouts_count = QtWidgets.QLabel(self.checkouts_card)
111 | checkouts_count = self.checkouts_count
112 | self.checkouts_count.setGeometry(QtCore.QRect(43, 10, 31, 31))
113 | self.checkouts_count.setFont(font)
114 | self.checkouts_count.setStyleSheet("color: #34C693;border: none;")
115 | self.checkouts_count.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
116 | self.checkouts_count.setText("0")
117 | self.tasks_total_card = QtWidgets.QWidget(self.homepage)
118 | self.tasks_total_card.setGeometry(QtCore.QRect(30, 45, 181, 51))
119 | self.tasks_total_card.setStyleSheet("background-color: #232323;border-radius: 10px;border: 1px solid #2e2d2d;")
120 | self.tasks_total_label = QtWidgets.QLabel(self.tasks_total_card)
121 | self.tasks_total_label.setGeometry(QtCore.QRect(80, 10, 91, 31))
122 | self.tasks_total_label.setFont(font)
123 | self.tasks_total_label.setStyleSheet("color: rgb(234, 239, 239);border: none;")
124 | self.tasks_total_label.setText("Total Tasks")
125 | self.tasks_total_icon = QtWidgets.QLabel(self.tasks_total_card)
126 | self.tasks_total_icon.setGeometry(QtCore.QRect(10, 10, 31, 31))
127 | self.tasks_total_icon.setStyleSheet("border: none;")
128 | self.tasks_total_icon.setText("")
129 | self.tasks_total_icon.setPixmap(QtGui.QPixmap(":/images/tasks.png"))
130 | self.tasks_total_icon.setScaledContents(True)
131 | global tasks_total_count
132 | self.tasks_total_count = QtWidgets.QLabel(self.tasks_total_card)
133 | tasks_total_count = self.tasks_total_count
134 | self.tasks_total_count.setGeometry(QtCore.QRect(43, 10, 31, 31))
135 | self.tasks_total_count.setFont(font)
136 | self.tasks_total_count.setStyleSheet("color: #755FF6;border: none;")
137 | self.tasks_total_count.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
138 | self.tasks_total_count.setText("0")
139 | self.carted_card = QtWidgets.QWidget(self.homepage)
140 | self.carted_card.setGeometry(QtCore.QRect(240, 45, 171, 51))
141 | self.carted_card.setStyleSheet("background-color: #232323;border-radius: 10px;border: 1px solid #2e2d2d;")
142 | self.carted_label = QtWidgets.QLabel(self.carted_card)
143 | self.carted_label.setGeometry(QtCore.QRect(80, 10, 90, 31))
144 | self.carted_label.setFont(font)
145 | self.carted_label.setStyleSheet("color: rgb(234, 239, 239);border: none;")
146 | self.carted_label.setText("Total Carts")
147 | self.carted_icon = QtWidgets.QLabel(self.carted_card)
148 | self.carted_icon.setGeometry(QtCore.QRect(10, 10, 31, 31))
149 | self.carted_icon.setStyleSheet("border: none;")
150 | self.carted_icon.setText("")
151 | self.carted_icon.setPixmap(QtGui.QPixmap(":/images/cart.png"))
152 | self.carted_icon.setScaledContents(True)
153 | global carted_count
154 | self.carted_count = QtWidgets.QLabel(self.carted_card)
155 | carted_count = self.carted_count
156 | self.carted_count.setGeometry(QtCore.QRect(43, 10, 31, 31))
157 | self.carted_count.setFont(font)
158 | self.carted_count.setStyleSheet("color: #F6905E;border: none;")
159 | self.carted_count.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
160 | self.carted_count.setText("0")
161 | self.buttons_card = QtWidgets.QWidget(self.homepage)
162 | self.buttons_card.setGeometry(QtCore.QRect(640, 45, 381, 51))
163 | self.buttons_card.setStyleSheet("background-color: #232323;border-radius: 10px;border: 1px solid #2e2d2d;")
164 | self.startall_btn = QtWidgets.QPushButton(self.buttons_card)
165 | self.startall_btn.setGeometry(QtCore.QRect(103, 10, 86, 32))
166 | font = QtGui.QFont()
167 | font.setFamily("Arial")
168 | self.startall_btn.setFont(font)
169 | self.startall_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
170 | self.startall_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border: none;")
171 | self.startall_btn.setText("Start All")
172 | self.startall_btn.clicked.connect(self.start_all_tasks)
173 | self.stopall_btn = QtWidgets.QPushButton(self.buttons_card)
174 | self.stopall_btn.setGeometry(QtCore.QRect(197, 10, 81, 32))
175 | self.stopall_btn.setFont(font)
176 | self.stopall_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
177 | self.stopall_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border: none;")
178 | self.stopall_btn.setText("Stop All")
179 | self.stopall_btn.clicked.connect(self.stop_all_tasks)
180 | self.deleteall_btn = QtWidgets.QPushButton(self.buttons_card)
181 | self.deleteall_btn.setGeometry(QtCore.QRect(285, 10, 86, 32))
182 | self.deleteall_btn.setFont(font)
183 | self.deleteall_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
184 | self.deleteall_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border: none;")
185 | self.deleteall_btn.setText("Delete All")
186 | self.deleteall_btn.clicked.connect(self.delete_all_tasks)
187 | self.newtask_btn = QtWidgets.QPushButton(self.buttons_card)
188 | self.newtask_btn.setGeometry(QtCore.QRect(10, 10, 86, 32))
189 | self.newtask_btn.setFont(font)
190 | self.newtask_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
191 | self.newtask_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border: none;")
192 | self.newtask_btn.setText("New Task")
193 | QtCore.QMetaObject.connectSlotsByName(homepage)
194 |
195 | def load_tasks(self):
196 | tasks_data = return_data("./data/tasks.json")
197 | write_data("./data/tasks.json",[])
198 | try:
199 | for task in tasks_data:
200 | tab = TaskTab(task["site"],task["product"],task["profile"],task["proxies"],task["monitor_delay"],task["error_delay"],task["max_price"],self.stop_all_tasks,self.scrollAreaWidgetContents)
201 | self.verticalLayout.takeAt(self.verticalLayout.count()-1)
202 | self.verticalLayout.addWidget(tab)
203 | spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
204 | self.verticalLayout.addItem(spacerItem)
205 | except:
206 | pass
207 |
208 | def set_settings_data(self,settings_data):
209 | global settings
210 | settings = settings_data
211 |
212 | def start_all_tasks(self):
213 | for task in self.tasks:
214 | try:
215 | task.start(None)
216 | except:
217 | pass
218 | def stop_all_tasks(self):
219 | for task in self.tasks:
220 | try:
221 | task.stop(None)
222 | except:
223 | pass
224 |
225 | def delete_all_tasks(self):
226 | for task in self.tasks:
227 | try:
228 | task.delete(None)
229 | except:
230 | pass
231 |
232 | class TaskTab(QtWidgets.QWidget):
233 | def __init__(self,site,product,profile,proxies,monitor_delay,error_delay,max_price,stop_all,parent=None):
234 | super(TaskTab, self).__init__(parent)
235 | self.task_id = str(int(tasks_total_count.text())+1)
236 | tasks_total_count.setText(self.task_id)
237 | self.site,self.product,self.profile,self.proxies,self.monitor_delay,self.error_delay,self.max_price,self.stop_all = site,product,profile,proxies,monitor_delay,error_delay,max_price,stop_all
238 | self.setupUi(self)
239 | tasks.append(self)
240 | tasks_data = return_data("./data/tasks.json")
241 | task_data = {"task_id": self.task_id,"site":self.site,"product": self.product,"profile": self.profile,"proxies": self.proxies,"monitor_delay": self.monitor_delay,"error_delay": self.error_delay,"max_price": self.max_price}
242 | tasks_data.append(task_data)
243 | write_data("./data/tasks.json",tasks_data)
244 | def setupUi(self,TaskTab):
245 | self.running = False
246 |
247 | self.TaskTab = TaskTab
248 | self.TaskTab.setMinimumSize(QtCore.QSize(0, 50))
249 | self.TaskTab.setMaximumSize(QtCore.QSize(16777215, 50))
250 | self.TaskTab.setStyleSheet("border-radius: none;")
251 | self.product_label = QtWidgets.QLabel(self.TaskTab)
252 | self.product_label.setGeometry(QtCore.QRect(222, 10, 331, 31))
253 | font = QtGui.QFont()
254 | font.setFamily("Arial")
255 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
256 | font.setBold(False)
257 | font.setWeight(50)
258 | self.product_label.setFont(font)
259 | self.product_label.setStyleSheet("color: rgb(234, 239, 239);")
260 | self.profile_label = QtWidgets.QLabel(self.TaskTab)
261 | self.profile_label.setGeometry(QtCore.QRect(571, 10, 51, 31))
262 | self.profile_label.setFont(font)
263 | self.profile_label.setStyleSheet("color: rgb(234, 239, 239);")
264 | self.status_label = QtWidgets.QLabel(self.TaskTab)
265 | self.status_label.setGeometry(QtCore.QRect(632, 10, 231, 31))
266 | self.status_label.setFont(font)
267 | self.status_label.setStyleSheet("color: rgb(234, 239, 239);")
268 | self.browser_label = QtWidgets.QLabel(self.TaskTab)
269 | self.browser_label.setGeometry(QtCore.QRect(632, 10, 231, 31))
270 | self.browser_label.setFont(font)
271 | self.browser_label.setStyleSheet("color: rgb(163, 149, 255);")
272 | self.browser_label.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
273 | self.browser_label.mousePressEvent = self.open_browser
274 | self.browser_label.hide()
275 | self.start_btn = QtWidgets.QLabel(self.TaskTab)
276 | self.start_btn.setGeometry(QtCore.QRect(870, 15, 16, 16))
277 | self.start_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
278 | self.start_btn.setPixmap(QtGui.QPixmap(":/images/play.png"))
279 | self.start_btn.setScaledContents(True)
280 | self.start_btn.mousePressEvent = self.start
281 | self.stop_btn = QtWidgets.QLabel(self.TaskTab)
282 | self.stop_btn.setGeometry(QtCore.QRect(870, 15, 16, 16))
283 | self.stop_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
284 | self.stop_btn.setPixmap(QtGui.QPixmap(":/images/stop.png"))
285 | self.stop_btn.setScaledContents(True)
286 | self.stop_btn.mousePressEvent = self.stop
287 | self.delete_btn = QtWidgets.QLabel(self.TaskTab)
288 | self.delete_btn.setGeometry(QtCore.QRect(920, 15, 16, 16))
289 | self.delete_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
290 | self.delete_btn.setPixmap(QtGui.QPixmap(":/images/trash.png"))
291 | self.delete_btn.setScaledContents(True)
292 | self.delete_btn.mousePressEvent = self.delete
293 | self.edit_btn = QtWidgets.QLabel(self.TaskTab)
294 | self.edit_btn.setGeometry(QtCore.QRect(895, 15, 16, 16))
295 | self.edit_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
296 | self.edit_btn.setPixmap(QtGui.QPixmap(":/images/edit.png"))
297 | self.edit_btn.setScaledContents(True)
298 | self.edit_btn.mousePressEvent = self.edit
299 | self.image = QtWidgets.QLabel(self.TaskTab)
300 | self.image.setGeometry(QtCore.QRect(20, 0, 50, 50))
301 | self.image.setPixmap(QtGui.QPixmap(":/images/no_image.png"))
302 | self.image.setScaledContents(True)
303 | self.site_label = QtWidgets.QLabel(self.TaskTab)
304 | self.site_label.setGeometry(QtCore.QRect(140, 10, 61, 31))
305 | self.site_label.setFont(font)
306 | self.site_label.setStyleSheet("color: rgb(234, 239, 239);")
307 | self.id_label = QtWidgets.QLabel(self.TaskTab)
308 | self.id_label.setGeometry(QtCore.QRect(90, 10, 31, 31))
309 | self.id_label.setFont(font)
310 | self.id_label.setStyleSheet("color: rgb(234, 239, 239);")
311 | self.stop_btn.raise_()
312 | self.product_label.raise_()
313 | self.profile_label.raise_()
314 | self.browser_label.raise_()
315 | self.start_btn.raise_()
316 | self.delete_btn.raise_()
317 | self.image.raise_()
318 | self.site_label.raise_()
319 | self.monitor_delay_label = QtWidgets.QLabel(self.TaskTab)
320 | self.monitor_delay_label.hide()
321 | self.error_delay_label = QtWidgets.QLabel(self.TaskTab)
322 | self.error_delay_label.hide()
323 | self.max_price_label = QtWidgets.QLabel(self.TaskTab)
324 | self.max_price_label.hide()
325 | self.proxies_label = QtWidgets.QLabel(self.TaskTab)
326 | self.proxies_label.hide()
327 | self.load_labels()
328 |
329 |
330 | def load_labels(self):
331 | self.id_label.setText(self.task_id)
332 | self.product_label.setText(self.product)
333 | self.profile_label.setText(self.profile)
334 | self.proxies_label.setText(self.proxies)
335 | self.status_label.setText("Idle")
336 | self.browser_label.setText("Click To Open Browser")
337 | self.site_label.setText(self.site)
338 | self.monitor_delay_label.setText(self.monitor_delay)
339 | self.error_delay_label.setText(self.error_delay)
340 | self.max_price_label.setText(self.max_price)
341 |
342 | def update_status(self,msg):
343 | self.status_label.setText(msg["msg"])
344 | if msg["msg"] == "Browser Ready":
345 | self.browser_url,self.browser_cookies = msg["url"],msg["cookies"]
346 | self.running = False
347 | self.start_btn.raise_()
348 | self.browser_label.show()
349 | logger.alt(self.task_id,msg["msg"])
350 | loop = QtCore.QEventLoop()
351 | QtCore.QTimer.singleShot(1000, loop.quit)
352 | loop.exec_()
353 | self.task.stop()
354 | return
355 | if msg["status"] == "idle":
356 | self.status_label.setStyleSheet("color: rgb(255, 255, 255);")
357 | logger.normal(self.task_id,msg["msg"])
358 | elif msg["status"] == "normal":
359 | self.status_label.setStyleSheet("color: rgb(163, 149, 255);")
360 | logger.normal(self.task_id,msg["msg"])
361 | elif msg["status"] == "alt":
362 | self.status_label.setStyleSheet("color: rgb(242, 166, 137);")
363 | logger.alt(self.task_id,msg["msg"])
364 | elif msg["status"] == "error":
365 | self.status_label.setStyleSheet("color: rgb(252, 81, 81);")
366 | logger.error(self.task_id,msg["msg"])
367 | elif msg["status"] == "success":
368 | self.status_label.setStyleSheet("color: rgb(52, 198, 147);")
369 | logger.success(self.task_id,msg["msg"])
370 | self.running = False
371 | self.start_btn.raise_()
372 | if settings.buy_one:
373 | self.stop_all()
374 | checkouts_count.setText(str(int(checkouts_count.text())+1))
375 | elif msg["status"] == "carted":
376 | self.status_label.setStyleSheet("color: rgb(163, 149, 255);")
377 | logger.alt(self.task_id,msg["msg"])
378 | carted_count.setText(str(int(carted_count.text())+1))
379 |
380 | def update_image(self,image_url):
381 | self.image_thread = ImageThread(image_url)
382 | self.image_thread.finished_signal.connect(self.set_image)
383 | self.image_thread.start()
384 |
385 | def set_image(self,pixmap):
386 | self.image.setPixmap(pixmap)
387 |
388 | def start(self,event):
389 | if not self.running:
390 | self.browser_label.hide()
391 | self.task = TaskThread()
392 | self.task.status_signal.connect(self.update_status)
393 | self.task.image_signal.connect(self.update_image)
394 | self.task.set_data(
395 | self.task_id,
396 | self.site_label.text(),
397 | self.product_label.text(),
398 | self.profile_label.text(),
399 | self.proxies_label.text(),
400 | self.monitor_delay_label.text(),
401 | self.error_delay_label.text(),
402 | self.max_price_label.text()
403 | )
404 | self.task.start()
405 | self.running = True
406 | self.stop_btn.raise_()
407 |
408 | def stop(self,event):
409 | self.task.stop()
410 | self.running = False
411 | self.update_status({"msg":"Stopped","status":"idle"})
412 | self.start_btn.raise_()
413 |
414 | def edit(self,event):
415 | self.edit_dialog = CreateDialog()
416 | self.edit_dialog.addtask_btn.clicked.connect(self.update_task)
417 | self.edit_dialog.taskcount_spinbox.hide()
418 | self.edit_dialog.profile_box.clear()
419 | self.edit_dialog.proxies_box.clear()
420 | profile_combobox = self.parent().parent().parent().parent().parent().parent().parent().createdialog.profile_box
421 | for profile in [profile_combobox.itemText(i) for i in range(profile_combobox.count())]:
422 | self.edit_dialog.profile_box.addItem(profile)
423 | proxies_combobox = self.parent().parent().parent().parent().parent().parent().parent().createdialog.proxies_box
424 | for proxy in [proxies_combobox.itemText(i) for i in range(proxies_combobox.count())]:
425 | self.edit_dialog.proxies_box.addItem(proxy)
426 | self.edit_dialog.load_data(self)
427 | self.edit_dialog.show()
428 |
429 | def update_task(self):
430 | self.site=self.edit_dialog.site_box.currentText()
431 | self.product=self.edit_dialog.input_edit.text()
432 | self.profile=self.edit_dialog.profile_box.currentText()
433 | self.proxies=self.edit_dialog.proxies_box.currentText()
434 | self.monitor_delay=self.edit_dialog.monitor_edit.text()
435 | self.error_delay = self.edit_dialog.error_edit.text()
436 | self.max_price = self.edit_dialog.price_edit.text()
437 | self.load_labels()
438 | self.delete_json()
439 | tasks_data = return_data("./data/tasks.json")
440 | task_data = {"task_id": self.task_id, "site": self.site, "product": self.product, "profile": self.profile,
441 | "proxies": self.proxies, "monitor_delay": self.monitor_delay, "error_delay": self.error_delay,
442 | "max_price": self.max_price}
443 | tasks_data.append(task_data)
444 | write_data("./data/tasks.json",tasks_data)
445 | self.edit_dialog.deleteLater()
446 |
447 | def delete_json(self):
448 | tasks_data = return_data("./data/tasks.json")
449 | for task in tasks_data:
450 | if task["task_id"] == self.task_id:
451 | tasks_data.remove(task)
452 | break
453 | write_data("./data/tasks.json", tasks_data)
454 |
455 | def delete(self,event):
456 | tasks_total_count.setText(str(int(tasks_total_count.text()) - 1))
457 | self.delete_json()
458 | self.TaskTab.deleteLater()
459 |
460 | def open_browser(self,event):
461 | self.browser_thread = BrowserThread()
462 | self.browser_thread.set_data(
463 | self.browser_url,
464 | self.browser_cookies
465 | )
466 | self.browser_thread.start()
467 | class TaskThread(QtCore.QThread):
468 | status_signal = QtCore.pyqtSignal("PyQt_PyObject")
469 | image_signal = QtCore.pyqtSignal("PyQt_PyObject")
470 | def __init__(self):
471 | QtCore.QThread.__init__(self)
472 |
473 | def set_data(self,task_id,site,product,profile,proxies,monitor_delay,error_delay,max_price):
474 | self.task_id,self.site,self.product,self.profile,self.proxies,self.monitor_delay,self.error_delay,self.max_price = task_id,site,product,profile,proxies,monitor_delay,error_delay,max_price
475 |
476 | def run(self):
477 | profile,proxy = get_profile(self.profile),get_proxy(self.proxies)
478 | if profile == None:
479 | self.status_signal.emit({"msg":"Invalid profile","status":"error"})
480 | return
481 | if proxy == None:
482 | self.status_signal.emit({"msg":"Invalid proxy list","status":"error"})
483 | return
484 | if self.site == "Walmart":
485 | Walmart(self.task_id,self.status_signal,self.image_signal,self.product,profile,proxy,self.monitor_delay,self.error_delay,self.max_price)
486 | elif self.site == "Bestbuy":
487 | BestBuy(self.task_id,self.status_signal,self.image_signal,self.product,profile,proxy,self.monitor_delay,self.error_delay)
488 |
489 | def stop(self):
490 | self.terminate()
491 |
492 | class ImageThread(QtCore.QThread):
493 | finished_signal = QtCore.pyqtSignal("PyQt_PyObject")
494 | def __init__(self,image_url):
495 | self.image_url = image_url
496 | QtCore.QThread.__init__(self)
497 |
498 | def run(self):
499 | data = urllib.request.urlopen(self.image_url).read()
500 | pixmap = QtGui.QPixmap()
501 | pixmap.loadFromData(data)
502 | self.finished_signal.emit(pixmap)
503 |
504 | class BrowserThread(QtCore.QThread):
505 | def __init__(self):
506 | QtCore.QThread.__init__(self)
507 |
508 | def set_data(self,url,cookies):
509 | self.url,self.cookies = url,cookies
510 | def run(self):
511 | open_browser(self.url,self.cookies)
512 |
513 |
--------------------------------------------------------------------------------
/pages/profilespage.py:
--------------------------------------------------------------------------------
1 | from PyQt5 import QtCore, QtGui, QtWidgets
2 | from utils import return_data,write_data,get_profile,Encryption
3 | import sys,platform
4 | def no_abort(a, b, c):
5 | sys.__excepthook__(a, b, c)
6 | sys.excepthook = no_abort
7 |
8 | class ProfilesPage(QtWidgets.QWidget):
9 | def __init__(self,parent=None):
10 | super(ProfilesPage, self).__init__(parent)
11 | self.setupUi(self)
12 | def setupUi(self, profilespage):
13 | self.profilespage = profilespage
14 | self.profilespage.setAttribute(QtCore.Qt.WA_StyledBackground, True)
15 | self.profilespage.setGeometry(QtCore.QRect(60, 0, 1041, 601))
16 | self.profilespage.setStyleSheet("QComboBox::drop-down { border: 0px;}QComboBox::down-arrow { image: url(:/images/down_icon.png); width: 14px; height: 14px;}QComboBox{ padding: 1px 0px 1px 3px;}QLineEdit:focus { border: none; outline: none;}")
17 | self.shipping_card = QtWidgets.QWidget(self.profilespage)
18 | self.shipping_card.setGeometry(QtCore.QRect(30, 70, 313, 501))
19 | self.shipping_card.setStyleSheet("background-color: #232323;border-radius: 20px;border: 1px solid #2e2d2d;")
20 | self.shipping_fname_edit = QtWidgets.QLineEdit(self.shipping_card)
21 | self.shipping_fname_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
22 | self.shipping_fname_edit.setGeometry(QtCore.QRect(30, 50, 113, 21))
23 | font = QtGui.QFont()
24 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
25 | font.setFamily("Arial")
26 | self.shipping_fname_edit.setFont(font)
27 | self.shipping_fname_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
28 | self.shipping_fname_edit.setPlaceholderText("First Name")
29 | self.shipping_header = QtWidgets.QLabel(self.shipping_card)
30 | self.shipping_header.setGeometry(QtCore.QRect(20, 10, 81, 31))
31 | font.setPointSize(18) if platform.system() == "Darwin" else font.setPointSize(18*.75)
32 | font.setBold(False)
33 | font.setWeight(50)
34 | self.shipping_header.setFont(font)
35 | self.shipping_header.setStyleSheet("color: rgb(212, 214, 214);border: none;")
36 | self.shipping_header.setText("Shipping")
37 | self.shipping_lname_edit = QtWidgets.QLineEdit(self.shipping_card)
38 | self.shipping_lname_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
39 | self.shipping_lname_edit.setGeometry(QtCore.QRect(170, 50, 113, 21))
40 | font = QtGui.QFont()
41 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
42 | font.setFamily("Arial")
43 | self.shipping_lname_edit.setFont(font)
44 | self.shipping_lname_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
45 | self.shipping_lname_edit.setPlaceholderText("Last Name")
46 | self.shipping_email_edit = QtWidgets.QLineEdit(self.shipping_card)
47 | self.shipping_email_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
48 | self.shipping_email_edit.setGeometry(QtCore.QRect(30, 100, 253, 21))
49 | self.shipping_email_edit.setFont(font)
50 | self.shipping_email_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
51 | self.shipping_email_edit.setPlaceholderText("Email Address")
52 | self.shipping_phone_edit = QtWidgets.QLineEdit(self.shipping_card)
53 | self.shipping_phone_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
54 | self.shipping_phone_edit.setGeometry(QtCore.QRect(30, 150, 253, 21))
55 | self.shipping_phone_edit.setFont(font)
56 | self.shipping_phone_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
57 | self.shipping_phone_edit.setPlaceholderText("Phone Number")
58 | self.shipping_address1_edit = QtWidgets.QLineEdit(self.shipping_card)
59 | self.shipping_address1_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
60 | self.shipping_address1_edit.setGeometry(QtCore.QRect(30, 200, 151, 21))
61 | self.shipping_address1_edit.setFont(font)
62 | self.shipping_address1_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
63 | self.shipping_address1_edit.setPlaceholderText("Address 1")
64 | self.shipping_address2_edit = QtWidgets.QLineEdit(self.shipping_card)
65 | self.shipping_address2_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
66 | self.shipping_address2_edit.setGeometry(QtCore.QRect(208, 200, 75, 21))
67 | self.shipping_address2_edit.setFont(font)
68 | self.shipping_address2_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
69 | self.shipping_address2_edit.setPlaceholderText("Address 2")
70 | self.shipping_city_edit = QtWidgets.QLineEdit(self.shipping_card)
71 | self.shipping_city_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
72 | self.shipping_city_edit.setGeometry(QtCore.QRect(30, 250, 151, 21))
73 | self.shipping_city_edit.setFont(font)
74 | self.shipping_city_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
75 | self.shipping_city_edit.setPlaceholderText("City")
76 | self.shipping_zipcode_edit = QtWidgets.QLineEdit(self.shipping_card)
77 | self.shipping_zipcode_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
78 | self.shipping_zipcode_edit.setGeometry(QtCore.QRect(208, 250, 75, 21))
79 | self.shipping_zipcode_edit.setFont(font)
80 | self.shipping_zipcode_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
81 | self.shipping_zipcode_edit.setPlaceholderText("Zip Code")
82 | self.shipping_state_box = QtWidgets.QComboBox(self.shipping_card)
83 | self.shipping_state_box.setGeometry(QtCore.QRect(30, 300, 253, 26))
84 | self.shipping_state_box.setFont(font)
85 | self.shipping_state_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
86 | self.shipping_state_box.addItem("State")
87 | self.shipping_country_box = QtWidgets.QComboBox(self.shipping_card)
88 | self.shipping_country_box.setGeometry(QtCore.QRect(30, 360, 253, 26))
89 | self.shipping_country_box.setFont(font)
90 | self.shipping_country_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
91 | self.shipping_country_box.addItem("Country")
92 | self.shipping_country_box.addItem("United States")
93 | self.profiles_header = QtWidgets.QLabel(self.profilespage)
94 | self.profiles_header.setGeometry(QtCore.QRect(30, 10, 81, 31))
95 | font.setPointSize(22) if platform.system() == "Darwin" else font.setPointSize(22*.75)
96 | font.setBold(False)
97 | font.setWeight(50)
98 | self.profiles_header.setFont(font)
99 | self.profiles_header.setStyleSheet("color: rgb(234, 239, 239);")
100 | self.profiles_header.setText("Profiles")
101 | self.billing_card = QtWidgets.QWidget(self.profilespage)
102 | self.billing_card.setGeometry(QtCore.QRect(365, 70, 313, 501))
103 | self.billing_card.setStyleSheet("background-color: #232323;border-radius: 20px;border: 1px solid #2e2d2d;")
104 | self.billing_fname_edit = QtWidgets.QLineEdit(self.billing_card)
105 | self.billing_fname_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
106 | self.billing_fname_edit.setGeometry(QtCore.QRect(30, 50, 113, 21))
107 | font = QtGui.QFont()
108 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
109 | font.setFamily("Arial")
110 | self.billing_fname_edit.setFont(font)
111 | self.billing_fname_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
112 | self.billing_fname_edit.setPlaceholderText("First Name")
113 | self.billing_header = QtWidgets.QLabel(self.billing_card)
114 | self.billing_header.setGeometry(QtCore.QRect(20, 10, 51, 31))
115 | font.setPointSize(18) if platform.system() == "Darwin" else font.setPointSize(18*.75)
116 | font.setBold(False)
117 | font.setWeight(50)
118 | self.billing_header.setFont(font)
119 | self.billing_header.setStyleSheet("color: rgb(212, 214, 214);border: none;")
120 | self.billing_header.setText("Billing")
121 | font = QtGui.QFont()
122 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
123 | font.setFamily("Arial")
124 | self.billing_lname_edit = QtWidgets.QLineEdit(self.billing_card)
125 | self.billing_lname_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
126 | self.billing_lname_edit.setGeometry(QtCore.QRect(170, 50, 113, 21))
127 | self.billing_lname_edit.setFont(font)
128 | self.billing_lname_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
129 | self.billing_lname_edit.setPlaceholderText("Last Name")
130 | self.billing_email_edit = QtWidgets.QLineEdit(self.billing_card)
131 | self.billing_email_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
132 | self.billing_email_edit.setGeometry(QtCore.QRect(30, 100, 253, 21))
133 | self.billing_email_edit.setFont(font)
134 | self.billing_email_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
135 | self.billing_email_edit.setPlaceholderText("Email Address")
136 | self.billing_phone_edit = QtWidgets.QLineEdit(self.billing_card)
137 | self.billing_phone_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
138 | self.billing_phone_edit.setGeometry(QtCore.QRect(30, 150, 253, 21))
139 | self.billing_phone_edit.setFont(font)
140 | self.billing_phone_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
141 | self.billing_phone_edit.setPlaceholderText("Phone Number")
142 | self.billing_address1_edit = QtWidgets.QLineEdit(self.billing_card)
143 | self.billing_address1_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
144 | self.billing_address1_edit.setGeometry(QtCore.QRect(30, 200, 151, 21))
145 | self.billing_address1_edit.setFont(font)
146 | self.billing_address1_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
147 | self.billing_address1_edit.setPlaceholderText("Address 1")
148 | self.billing_address2_edit = QtWidgets.QLineEdit(self.billing_card)
149 | self.billing_address2_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
150 | self.billing_address2_edit.setGeometry(QtCore.QRect(208, 200, 75, 21))
151 | self.billing_address2_edit.setFont(font)
152 | self.billing_address2_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
153 | self.billing_address2_edit.setPlaceholderText("Address 2")
154 | self.billing_city_edit = QtWidgets.QLineEdit(self.billing_card)
155 | self.billing_city_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
156 | self.billing_city_edit.setGeometry(QtCore.QRect(30, 250, 151, 21))
157 | self.billing_city_edit.setFont(font)
158 | self.billing_city_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
159 | self.billing_city_edit.setPlaceholderText("City")
160 | self.billing_zipcode_edit = QtWidgets.QLineEdit(self.billing_card)
161 | self.billing_zipcode_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
162 | self.billing_zipcode_edit.setGeometry(QtCore.QRect(208, 250, 75, 21))
163 | self.billing_zipcode_edit.setFont(font)
164 | self.billing_zipcode_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
165 | self.billing_zipcode_edit.setPlaceholderText("Zip Code")
166 | self.billing_state_box = QtWidgets.QComboBox(self.billing_card)
167 | self.billing_state_box.setGeometry(QtCore.QRect(30, 300, 253, 26))
168 | self.billing_state_box.setFont(font)
169 | self.billing_state_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
170 | self.billing_state_box.addItem("State")
171 | self.billing_country_box = QtWidgets.QComboBox(self.billing_card)
172 | self.billing_country_box.setGeometry(QtCore.QRect(30, 360, 253, 26))
173 | self.billing_country_box.setFont(font)
174 | self.billing_country_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
175 | self.billing_country_box.addItem("Country")
176 | self.billing_country_box.addItem("United States")
177 | self.same_shipping_checkbox = QtWidgets.QCheckBox(self.billing_card)
178 | self.same_shipping_checkbox.setGeometry(QtCore.QRect(160, 16, 131, 20))
179 | self.same_shipping_checkbox.setFont(font)
180 | self.same_shipping_checkbox.setStyleSheet("border:none;color: rgb(234, 239, 239);")
181 | self.same_shipping_checkbox.setText("Same as shipping")
182 | self.same_shipping_checkbox.stateChanged.connect(self.same_shipping_checkbox_clicked)
183 | self.tasks_card_3 = QtWidgets.QWidget(self.profilespage)
184 | self.tasks_card_3.setGeometry(QtCore.QRect(700, 70, 313, 501))
185 | self.tasks_card_3.setStyleSheet("background-color: #232323;border-radius: 20px;border: 1px solid #2e2d2d;")
186 | self.payment_header = QtWidgets.QLabel(self.tasks_card_3)
187 | self.payment_header.setGeometry(QtCore.QRect(20, 10, 81, 31))
188 | font.setPointSize(18) if platform.system() == "Darwin" else font.setPointSize(18*.75)
189 | font.setBold(False)
190 | font.setWeight(50)
191 | self.payment_header.setFont(font)
192 | self.payment_header.setStyleSheet("color: rgb(212, 214, 214);border: none;")
193 | self.payment_header.setText("Payment")
194 | self.cardnumber_edit = QtWidgets.QLineEdit(self.tasks_card_3)
195 | self.cardnumber_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
196 | self.cardnumber_edit.setGeometry(QtCore.QRect(30, 100, 151, 21))
197 | font = QtGui.QFont()
198 | font.setFamily("Arial")
199 | self.cardnumber_edit.setFont(font)
200 | self.cardnumber_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
201 | self.cardnumber_edit.setPlaceholderText("Card Number")
202 | self.cardcvv_edit = QtWidgets.QLineEdit(self.tasks_card_3)
203 | self.cardcvv_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
204 | self.cardcvv_edit.setGeometry(QtCore.QRect(208, 100, 75, 21))
205 | self.cardcvv_edit.setFont(font)
206 | self.cardcvv_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
207 | self.cardcvv_edit.setPlaceholderText("CVV")
208 | self.save_btn = QtWidgets.QPushButton(self.tasks_card_3)
209 | self.save_btn.setGeometry(QtCore.QRect(70, 300, 86, 32))
210 | self.save_btn.setFont(font)
211 | self.save_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
212 | self.save_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border-radius: 10px;border: 1px solid #2e2d2d;")
213 | self.save_btn.setText("Save")
214 | self.save_btn.clicked.connect(self.save_profile)
215 | self.cardtype_box = QtWidgets.QComboBox(self.tasks_card_3)
216 | self.cardtype_box.setGeometry(QtCore.QRect(30, 50, 253, 26))
217 | self.cardtype_box.setFont(font)
218 | self.cardtype_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
219 | self.cardtype_box.addItem("Card Type")
220 | self.cardmonth_box = QtWidgets.QComboBox(self.tasks_card_3)
221 | self.cardmonth_box.setGeometry(QtCore.QRect(30, 150, 113, 26))
222 | self.cardmonth_box.setFont(font)
223 | self.cardmonth_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
224 | self.cardmonth_box.addItem("Month")
225 | self.cardyear_box = QtWidgets.QComboBox(self.tasks_card_3)
226 | self.cardyear_box.setGeometry(QtCore.QRect(170, 150, 113, 26))
227 | self.cardyear_box.setFont(font)
228 | self.cardyear_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
229 | self.cardyear_box.addItem("Year")
230 | self.profile_header = QtWidgets.QLabel(self.tasks_card_3)
231 | self.profile_header.setGeometry(QtCore.QRect(20, 220, 81, 31))
232 | font.setPointSize(18) if platform.system() == "Darwin" else font.setPointSize(18*.75)
233 | font.setBold(False)
234 | font.setWeight(50)
235 | self.profile_header.setFont(font)
236 | self.profile_header.setStyleSheet("color: rgb(212, 214, 214);border: none;")
237 | self.profile_header.setText("Profile")
238 | self.profilename_edit = QtWidgets.QLineEdit(self.tasks_card_3)
239 | self.profilename_edit.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0)
240 | self.profilename_edit.setGeometry(QtCore.QRect(30, 260, 253, 21))
241 | font = QtGui.QFont()
242 | font.setPointSize(13) if platform.system() == "Darwin" else font.setPointSize(13*.75)
243 | font.setFamily("Arial")
244 | self.profilename_edit.setFont(font)
245 | self.profilename_edit.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
246 | self.profilename_edit.setPlaceholderText("Profile Name")
247 | self.loadprofile_box = QtWidgets.QComboBox(self.tasks_card_3)
248 | self.loadprofile_box.setGeometry(QtCore.QRect(30, 350, 253, 26))
249 | self.loadprofile_box.setFont(font)
250 | self.loadprofile_box.setStyleSheet("outline: 0;border: 1px solid #5D43FB;border-width: 0 0 2px;color: rgb(234, 239, 239);")
251 | self.loadprofile_box.addItem("Load Profile")
252 | self.loadprofile_box.currentTextChanged.connect(self.load_profile)
253 | self.delete_btn = QtWidgets.QPushButton(self.tasks_card_3)
254 | self.delete_btn.setGeometry(QtCore.QRect(167, 300, 86, 32))
255 | self.delete_btn.setFont(font)
256 | self.delete_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
257 | self.delete_btn.setStyleSheet("color: #FFFFFF;background-color: #5D43FB;border-radius: 10px;border: 1px solid #2e2d2d;")
258 | self.delete_btn.setText("Delete")
259 | self.delete_btn.clicked.connect(self.delete_profile)
260 | self.set_data()
261 | QtCore.QMetaObject.connectSlotsByName(profilespage)
262 |
263 | def set_data(self):
264 | for state in ["AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VI", "VA", "WA", "WV", "WI", "WY"]:
265 | self.shipping_state_box.addItem(state)
266 | self.billing_state_box.addItem(state)
267 | for month in range(1,13):
268 | self.cardmonth_box.addItem(str(month)) if month>9 else self.cardmonth_box.addItem("0"+str(month))
269 | for year in range(2020,2031):
270 | self.cardyear_box.addItem(str(year))
271 | for card_type in ["Visa", "Mastercard", "American Express", "Discover"]:
272 | self.cardtype_box.addItem(card_type)
273 | profiles = return_data("./data/profiles.json")
274 | for profile in profiles:
275 | profile_name = profile["profile_name"]
276 | self.loadprofile_box.addItem(profile_name)
277 | self.parent().parent().createdialog.profile_box.addItem(profile_name)
278 |
279 | def same_shipping_checkbox_clicked(self):
280 | if self.same_shipping_checkbox.isChecked():
281 | self.billing_country_box.setCurrentIndex(self.billing_country_box.findText(self.shipping_country_box.currentText()))
282 | self.billing_fname_edit.setText(self.shipping_fname_edit.text())
283 | self.billing_lname_edit.setText(self.shipping_lname_edit.text())
284 | self.billing_email_edit.setText(self.shipping_email_edit.text())
285 | self.billing_phone_edit.setText(self.shipping_phone_edit.text())
286 | self.billing_address1_edit.setText(self.shipping_address1_edit.text())
287 | self.billing_address2_edit.setText(self.shipping_address2_edit.text())
288 | self.billing_city_edit.setText(self.shipping_city_edit.text())
289 | self.billing_zipcode_edit.setText(self.shipping_zipcode_edit.text())
290 | self.billing_state_box.setCurrentIndex(self.billing_state_box.findText(self.shipping_state_box.currentText()))
291 |
292 | def load_profile(self):
293 | profile_name = self.loadprofile_box.currentText()
294 | p = get_profile(profile_name)
295 | if p is not None:
296 | self.profilename_edit.setText(p["profile_name"])
297 | self.shipping_fname_edit.setText(p["shipping_fname"])
298 | self.shipping_lname_edit.setText(p["shipping_lname"])
299 | self.shipping_email_edit.setText(p["shipping_email"])
300 | self.shipping_phone_edit.setText(p["shipping_phone"])
301 | self.shipping_address1_edit.setText(p["shipping_a1"])
302 | self.shipping_address2_edit.setText(p["shipping_a2"])
303 | self.shipping_city_edit.setText(p["shipping_city"])
304 | self.shipping_zipcode_edit.setText(p["shipping_zipcode"])
305 | self.shipping_state_box.setCurrentIndex(self.shipping_state_box.findText(p["shipping_state"]))
306 | self.shipping_country_box.setCurrentIndex(self.shipping_country_box.findText(p["shipping_country"]))
307 | self.billing_fname_edit.setText(p["billing_fname"])
308 | self.billing_lname_edit.setText(p["billing_lname"])
309 | self.billing_email_edit.setText(p["billing_email"])
310 | self.billing_phone_edit.setText(p["billing_phone"])
311 | self.billing_address1_edit.setText(p["billing_a1"])
312 | self.billing_address2_edit.setText(p["billing_a2"])
313 | self.billing_city_edit.setText(p["billing_city"])
314 | self.billing_zipcode_edit.setText(p["billing_zipcode"])
315 | self.billing_state_box.setCurrentIndex(self.billing_state_box.findText(p["billing_state"]))
316 | self.billing_country_box.setCurrentIndex(self.billing_country_box.findText(p["billing_country"]))
317 | self.cardnumber_edit.setText(p["card_number"])
318 | self.cardmonth_box.setCurrentIndex(self.cardmonth_box.findText(p["card_month"]))
319 | self.cardyear_box.setCurrentIndex(self.cardyear_box.findText(p["card_year"]))
320 | self.cardtype_box.setCurrentIndex(self.cardtype_box.findText(p["card_type"]))
321 | self.cardcvv_edit.setText(p["card_cvv"])
322 | return
323 | def save_profile(self):
324 | profile_name = self.profilename_edit.text()
325 | profile_data={
326 | "profile_name":profile_name,
327 | "shipping_fname": self.shipping_fname_edit.text(),
328 | "shipping_lname": self.shipping_lname_edit.text(),
329 | "shipping_email": self.shipping_email_edit.text(),
330 | "shipping_phone": self.shipping_phone_edit.text(),
331 | "shipping_a1": self.shipping_address1_edit.text(),
332 | "shipping_a2": self.shipping_address2_edit.text(),
333 | "shipping_city": self.shipping_city_edit.text(),
334 | "shipping_zipcode": self.shipping_zipcode_edit.text(),
335 | "shipping_state": self.shipping_state_box.currentText(),
336 | "shipping_country": self.shipping_country_box.currentText(),
337 | "billing_fname": self.billing_fname_edit.text(),
338 | "billing_lname": self.billing_lname_edit.text(),
339 | "billing_email": self.billing_email_edit.text(),
340 | "billing_phone": self.billing_phone_edit.text(),
341 | "billing_a1": self.billing_address1_edit.text(),
342 | "billing_a2": self.billing_address2_edit.text(),
343 | "billing_city": self.billing_city_edit.text(),
344 | "billing_zipcode": self.billing_zipcode_edit.text(),
345 | "billing_state": self.billing_state_box.currentText(),
346 | "billing_country": self.billing_country_box.currentText(),
347 | "card_number": (Encryption().encrypt(self.cardnumber_edit.text())).decode("utf-8"),
348 | "card_month": self.cardmonth_box.currentText(),
349 | "card_year": self.cardyear_box.currentText(),
350 | "card_type": self.cardtype_box.currentText(),
351 | "card_cvv": self.cardcvv_edit.text()
352 | }
353 | profiles = return_data("./data/profiles.json")
354 | for p in profiles:
355 | if p["profile_name"] == profile_name:
356 | profiles.remove(p)
357 | break
358 | profiles.append(profile_data)
359 | write_data("./data/profiles.json",profiles)
360 | if self.loadprofile_box.findText(profile_name) == -1:
361 | self.loadprofile_box.addItem(profile_name)
362 | self.parent().parent().createdialog.profile_box.addItem(profile_name)
363 | QtWidgets.QMessageBox.information(self, "Bird Bot", "Saved Profile")
364 |
365 | def delete_profile(self):
366 | profile_name = self.profilename_edit.text()
367 | profiles = return_data("./data/profiles.json")
368 | for profile in profiles:
369 | if profile["profile_name"] == profile_name:
370 | profiles.remove(profile)
371 | break
372 | write_data("./data/profiles.json",profiles)
373 | self.loadprofile_box.removeItem(self.loadprofile_box.findText(profile_name))
374 | self.parent().parent().createdialog.profile_box.removeItem(self.parent().parent().createdialog.profile_box.findText(profile_name))
375 |
376 | self.loadprofile_box.setCurrentIndex(0)
377 | self.profilename_edit.setText("")
378 | self.profilename_edit.setText("")
379 | self.shipping_fname_edit.setText("")
380 | self.shipping_lname_edit.setText("")
381 | self.shipping_email_edit.setText("")
382 | self.shipping_phone_edit.setText("")
383 | self.shipping_address1_edit.setText("")
384 | self.shipping_address2_edit.setText("")
385 | self.shipping_city_edit.setText("")
386 | self.shipping_zipcode_edit.setText("")
387 | self.shipping_state_box.setCurrentIndex(0)
388 | self.shipping_country_box.setCurrentIndex(0)
389 | self.billing_fname_edit.setText("")
390 | self.billing_lname_edit.setText("")
391 | self.billing_email_edit.setText("")
392 | self.billing_phone_edit.setText("")
393 | self.billing_address1_edit.setText("")
394 | self.billing_address2_edit.setText("")
395 | self.billing_city_edit.setText("")
396 | self.billing_zipcode_edit.setText("")
397 | self.billing_state_box.setCurrentIndex(0)
398 | self.billing_country_box.setCurrentIndex(0)
399 | self.cardnumber_edit.setText("")
400 | self.cardmonth_box.setCurrentIndex(0)
401 | self.cardyear_box.setCurrentIndex(0)
402 | self.cardtype_box.setCurrentIndex(0)
403 | self.cardcvv_edit.setText("")
404 | QtWidgets.QMessageBox.information(self, "Bird Bot", "Deleted Profile")
405 |
--------------------------------------------------------------------------------
/sites/bestbuy.py:
--------------------------------------------------------------------------------
1 | try:
2 | from Crypto.PublicKey import RSA
3 | from Crypto.Cipher import PKCS1_OAEP
4 | except:
5 | from Cryptodome.PublicKey import RSA
6 | from Cryptodome.Cipher import PKCS1_OAEP
7 | from base64 import b64encode
8 | from utils import send_webhook
9 | import requests,time,lxml.html,json,sys,settings
10 |
11 | class BestBuy:
12 | def __init__(self,task_id,status_signal,image_signal,product,profile,proxy,monitor_delay,error_delay):
13 | self.status_signal,self.image_signal,self.product,self.profile,self.monitor_delay,self.error_delay = status_signal,image_signal,product,profile,float(monitor_delay),float(error_delay)
14 | self.session = requests.Session()
15 | if proxy != False:
16 | self.session.proxies.update(proxy)
17 | self.status_signal.emit({"msg":"Starting","status":"normal"})
18 | tas_data = self.get_tas_data()
19 | product_image = self.monitor()
20 | self.atc()
21 | self.start_checkout()
22 | self.submit_shipping()
23 | self.submit_payment(tas_data)
24 | while True:
25 | success,jwt = self.submit_order()
26 | if not success and jwt != None:
27 | transaction_id = self.handle_3dsecure(jwt)
28 | self.submit_card(transaction_id)
29 | else:
30 | if success:
31 | send_webhook("OP","Bestbuy",self.profile["profile_name"],task_id,product_image)
32 | else:
33 | if settings.browser_on_failed:
34 | self.status_signal.emit({"msg":"Browser Ready","status":"alt","url":"https://www.bestbuy.com/checkout/r/fulfillment","cookies":[{"name":cookie.name,"value":cookie.value,"domain":cookie.domain} for cookie in self.session.cookies]})
35 | send_webhook("B","Bestbuy",self.profile["profile_name"],task_id,product_image)
36 | else:
37 | send_webhook("PF","Bestbuy",self.profile["profile_name"],task_id,product_image)
38 | break
39 |
40 | def get_tas_data(self):
41 | headers={
42 | "accept": "*/*",
43 | "accept-encoding": "gzip, deflate, br",
44 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
45 | "content-type": "application/json",
46 | "referer": "https://www.bestbuy.com/checkout/r/payment",
47 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
48 | }
49 | while True:
50 | try:
51 | self.status_signal.emit({"msg":"Getting TAS Data","status":"normal"})
52 | r = requests.get("https://www.bestbuy.com/api/csiservice/v2/key/tas",headers=headers)
53 | self.status_signal.emit({"msg":"Got TAS Data","status":"normal"})
54 | return json.loads(r.text)
55 | except Exception as e:
56 | self.status_signal.emit({"msg":"Error Getting TAS Data(line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
57 | time.sleep(self.error_delay)
58 | def monitor(self):
59 | headers = {
60 | "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
61 | "accept-encoding": "gzip, deflate, br",
62 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
63 | "cache-control": "max-age=0",
64 | "upgrade-insecure-requests": "1",
65 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36"
66 | }
67 | image_found = False
68 | product_image = ""
69 | while True:
70 | self.status_signal.emit({"msg":"Loading Product Page","status":"normal"})
71 | try:
72 | r = self.session.get(self.product,headers=headers)
73 | if r.status_code == 200:
74 | doc = lxml.html.fromstring(r.text)
75 | if not image_found:
76 | self.sku_id = doc.xpath('//span[@class="product-data-value body-copy"]/text()')[1].strip()
77 | product_image = doc.xpath('//img[@class="primary-image"]/@src')[0]
78 | self.image_signal.emit(product_image)
79 | image_found = True
80 | if self.check_stock():
81 | return product_image
82 | self.status_signal.emit({"msg":"Waiting For Restock","status":"normal"})
83 | time.sleep(self.monitor_delay)
84 | else:
85 | self.status_signal.emit({"msg":"Product Not Found","status":"normal"})
86 | time.sleep(self.monitor_delay)
87 | except Exception as e:
88 | self.status_signal.emit({"msg":"Error Loading Product Page (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
89 | time.sleep(self.error_delay)
90 |
91 | def check_stock(self):
92 | headers = {
93 | "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
94 | "accept-encoding": "gzip, deflate, br",
95 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
96 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
97 | }
98 | while True:
99 | self.status_signal.emit({"msg":"Checking Stock","status":"normal"})
100 | try:
101 | url = "https://www.bestbuy.com/api/tcfb/model.json?paths=%5B%5B%22shop%22%2C%22scds%22%2C%22v2%22%2C%22page%22%2C%22tenants%22%2C%22bbypres%22%2C%22pages%22%2C%22globalnavigationv5sv%22%2C%22header%22%5D%2C%5B%22shop%22%2C%22buttonstate%22%2C%22v5%22%2C%22item%22%2C%22skus%22%2C{}%2C%22conditions%22%2C%22NONE%22%2C%22destinationZipCode%22%2C%22%2520%22%2C%22storeId%22%2C%22%2520%22%2C%22context%22%2C%22cyp%22%2C%22addAll%22%2C%22false%22%5D%5D&method=get".format(self.sku_id)
102 | r = self.session.get(url,headers=headers)
103 | return "ADD_TO_CART" in r.text
104 | except Exception as e:
105 | self.status_signal.emit({"msg":"Error Checking Stock (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
106 | time.sleep(self.error_delay)
107 |
108 | def atc(self):
109 | headers={
110 | "accept": "application/json",
111 | "accept-encoding": "gzip, deflate, br",
112 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
113 | "content-length": "31",
114 | "content-type": "application/json; charset=UTF-8",
115 | "origin": "https://www.bestbuy.com",
116 | "referer": self.product,
117 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
118 | }
119 | body = {"items":[{"skuId":self.sku_id}]}
120 | while True:
121 | self.status_signal.emit({"msg":"Adding To Cart","status":"normal"})
122 | try:
123 | r = self.session.post("https://www.bestbuy.com/cart/api/v1/addToCart",json=body,headers=headers)
124 | if r.status_code == 200 and json.loads(r.text)["cartCount"] == 1:
125 | self.status_signal.emit({"msg":"Added To Cart","status":"carted"})
126 | return
127 | else:
128 | self.status_signal.emit({"msg":"Error Adding To Cart","status":"error"})
129 | time.sleep(self.error_delay)
130 | except Exception as e:
131 | self.status_signal.emit({"msg":"Error Adding To Cart (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
132 | time.sleep(self.error_delay)
133 |
134 | def start_checkout(self):
135 | headers = {
136 | "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
137 | "accept-encoding": "gzip, deflate, br",
138 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
139 | "upgrade-insecure-requests": "1",
140 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36",
141 | }
142 | while True:
143 | self.status_signal.emit({"msg":"Starting Checkout","status":"normal"})
144 | try:
145 | r = self.session.get("https://www.bestbuy.com/checkout/r/fufillment",headers=headers)
146 | if r.status_code == 200:
147 | r = json.loads(r.text.split("var orderData = ")[1].split(";")[0])
148 | self.order_id = r["id"]
149 | self.item_id = r["items"][0]["id"]
150 | self.status_signal.emit({"msg":"Started Checkout","status":"normal"})
151 | return
152 | self.status_signal.emit({"msg":"Error Starting Checkout","status":"error"})
153 | time.sleep(self.error_delay)
154 | except Exception as e:
155 | self.status_signal.emit({"msg":"Error Starting Checkout (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
156 | time.sleep(self.error_delay)
157 |
158 | def submit_shipping(self):
159 | headers={
160 | "accept": "application/com.bestbuy.order+json",
161 | "accept-encoding": "gzip, deflate, br",
162 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
163 | "content-type": "application/json",
164 | "origin": "https://www.bestbuy.com",
165 | "referer": "https://www.bestbuy.com/checkout/r/fulfillment",
166 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36",
167 | "x-user-interface": "DotCom-Optimized"
168 | }
169 | profile = self.profile
170 | body = {"items":[{"id":self.item_id,"type":"DEFAULT","selectedFulfillment":{"shipping":{"address":{
171 | "country":"US",
172 | "saveToProfile":False,
173 | "street2":profile["shipping_a2"],
174 | "useAddressAsBilling":False,
175 | "middleInitial":"",
176 | "lastName":profile["shipping_lname"],
177 | "street":profile["shipping_a1"],
178 | "city":profile["shipping_city"],
179 | "override":False,
180 | "zipcode":profile["shipping_zipcode"],
181 | "state":profile["shipping_state"],
182 | "firstName":profile["shipping_fname"],
183 | "isWishListAddress":False,
184 | "dayPhoneNumber":profile["shipping_phone"],"type":"RESIDENTIAL"}}},"giftMessageSelected":False}],
185 | "phoneNumber":profile["shipping_phone"],
186 | "smsNotifyNumber":"",
187 | "smsOptIn":False,
188 | "emailAddress":profile["shipping_email"]}
189 | while True:
190 | self.status_signal.emit({"msg":"Submitting Shipping","status":"normal"})
191 | try:
192 | r = self.session.patch("https://www.bestbuy.com/checkout/orders/{}/".format(self.order_id),json=body,headers=headers)
193 | if json.loads(r.text)["id"] == self.order_id:
194 | self.status_signal.emit({"msg":"Submitted Shipping","status":"normal"})
195 | return
196 | self.status_signal.emit({"msg":"Error Submitting Shipping","status":"error"})
197 | time.sleep(self.error_delay)
198 | except Exception as e:
199 | self.status_signal.emit({"msg":"Error Submitting Shipping (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
200 | time.sleep(self.error_delay)
201 |
202 | def submit_payment(self,tas_data):
203 | headers={
204 | "accept": "application/com.bestbuy.order+json",
205 | "accept-encoding": "gzip, deflate, br",
206 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
207 | "content-type": "application/json",
208 | "origin": "https://www.bestbuy.com",
209 | "referer": "https://www.bestbuy.com/checkout/r/fulfillment",
210 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36",
211 | "x-user-interface": "DotCom-Optimized"
212 | }
213 | profile = self.profile
214 | card_number = profile["card_number"]
215 | key = RSA.importKey(tas_data["publicKey"])
216 | cipher = PKCS1_OAEP.new(key)
217 | encrypted_card = b64encode(cipher.encrypt(("00926999"+card_number).encode("utf-8"))).decode("utf-8")
218 | zero_string = ""
219 | for i in range(len(card_number)-10):
220 | zero_string+="0"
221 | self.bin_number = card_number[:6]
222 | encrypted_card +=":3:"+tas_data["keyId"]+":"+self.bin_number+zero_string+card_number[-4:]
223 | body = {"billingAddress":{
224 | "country":"US",
225 | "saveToProfile":False,
226 | "street2": profile["billing_a2"],
227 | "useAddressAsBilling": True,
228 | "middleInitial":"",
229 | "lastName": profile["billing_lname"],
230 | "street": profile["billing_a1"],
231 | "city": profile["billing_city"],
232 | "override":False,
233 | "zipcode": profile["billing_zipcode"],
234 | "state": profile["billing_state"],
235 | "dayPhoneNumber": profile["billing_phone"],
236 | "firstName": profile["billing_fname"],
237 | "isWishListAddress":False},
238 | "creditCard":{
239 | "hasCID":False,
240 | "invalidCard":False,
241 | "isCustomerCard":False,
242 | "isNewCard":True,
243 | "isVisaCheckout":False,
244 | "govPurchaseCard":False,
245 | "isInternationalCard":False,
246 | "number": encrypted_card,
247 | "binNumber": self.bin_number,
248 | "cardType": profile["card_type"].upper(),
249 | "cid": profile["card_cvv"],
250 | "expiration":{"month": profile["card_month"],"year": profile["card_year"]},
251 | "isPWPRegistered":False}}
252 | while True:
253 | self.status_signal.emit({"msg":"Submitting Payment","status":"normal"})
254 | try:
255 | r = self.session.patch("https://www.bestbuy.com/checkout/orders/{}/paymentMethods".format(self.order_id),json=body,headers=headers)
256 | r = json.loads(r.text)
257 | if r["id"] == self.order_id:
258 | self.status_signal.emit({"msg":"Submitted Payment","status":"normal"})
259 | return
260 | self.status_signal.emit({"msg":"Error Submitting Payment","status":"error"})
261 | time.sleep(self.error_delay)
262 | except Exception as e:
263 | self.status_signal.emit({"msg":"Error Submitting Payment (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
264 | time.sleep(self.error_delay)
265 |
266 | def submit_order(self):
267 | headers = {
268 | "accept": "application/com.bestbuy.order+json",
269 | "accept-encoding": "gzip, deflate, br",
270 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
271 | "content-type": "application/json",
272 | "origin": "https://www.bestbuy.com",
273 | "referer": "https://www.bestbuy.com/checkout/r/payment",
274 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36",
275 | "x-user-interface": "DotCom-Optimized"
276 | }
277 | body = {"browserInfo":{"javaEnabled":False,"language":"en-US","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36","height":"1057","width":"1057","timeZone":"240","colorDepth":"24"}}
278 | while True:
279 | self.status_signal.emit({"msg":"Submitting Order","status":"alt"})
280 | try:
281 | r = self.session.post("https://www.bestbuy.com/checkout/orders/{}/".format(self.order_id),json=body,headers=headers)
282 | r = json.loads(r.text)
283 | try:
284 | r = r["errors"][0]
285 | if r["errorCode"] == "PAY_SECURE_REDIRECT":
286 | self.status_signal.emit({"msg":"3DSecure Found, Starting Auth Process","status":"error"})
287 | return False, r["paySecureResponse"]["stepUpJwt"]
288 | except:
289 | if r["state"] == "SUBMITTED":
290 | self.status_signal.emit({"msg":"Order Placed","status":"success"})
291 | return True, None
292 | self.status_signal.emit({"msg":"Payment Failed","status":"error"})
293 | return False, None
294 |
295 | except Exception as e:
296 | self.status_signal.emit({"msg":"Error Submitting Order (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
297 | time.sleep(self.error_delay)
298 |
299 | def handle_3dsecure(self,jwt):
300 | headers = {
301 | "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
302 | "accept-encoding": "gzip, deflate, br",
303 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
304 | "cache-control": "max-age=0",
305 | "content-type": "application/x-www-form-urlencoded",
306 | "origin": "https://www.bestbuy.com",
307 | "referer": "https://www.bestbuy.com/",
308 | "upgrade-insecure-requests": "1",
309 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
310 | }
311 | body = {
312 | "JWT": jwt,
313 | "TermUrl": "/payment/r/threeDSecure/redirect",
314 | "MD": ""
315 | }
316 | while True:
317 | self.status_signal.emit({"msg":"Authorizing Card (1)","status":"normal"})
318 | try:
319 | r = self.session.post("https://centinelapi.cardinalcommerce.com/V2/Cruise/StepUp",data=body,headers=headers)
320 | doc = lxml.html.fromstring(r.text)
321 | pa_req = doc.xpath('//input[@id="payload"]/@value')[0]
322 | md = doc.xpath('//input[@id="mcsId"]/@value')[0]
323 | term_url = doc.xpath('//input[@id="termUrl"]/@value')[0]
324 | acs_url = doc.xpath('//input[@id="acsUrl"]/@value')[0]
325 | break
326 | except Exception as e:
327 | self.status_signal.emit({"msg":"Error Authorizing Card (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
328 | time.sleep(self.error_delay)
329 | headers = {
330 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
331 | "Accept-Encoding": "gzip, deflate, br",
332 | "Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
333 | "Cache-Control": "max-age=0",
334 | "Connection": "keep-alive",
335 | "Content-Type": "application/x-www-form-urlencoded",
336 | "Host": "1eaf.cardinalcommerce.com",
337 | "Origin": "https://centinelapi.cardinalcommerce.com",
338 | "Referer": "https://centinelapi.cardinalcommerce.com/",
339 | "Upgrade-Insecure-Requests": "1",
340 | "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
341 | }
342 | body = {
343 | "PaReq": pa_req,
344 | "MD": md,
345 | "TermUrl": term_url
346 | }
347 | while True:
348 | self.status_signal.emit({"msg":"Authorizing Card (2)","status":"normal"})
349 | try:
350 | r = self.session.post(acs_url,data=body,headers=headers)
351 | doc = lxml.html.fromstring(r.text)
352 | pa_req = doc.xpath('//input[@name="PaReq"]/@value')[0]
353 | term_url = doc.xpath('//input[@name="TermUrl"]/@value')[0]
354 | md = doc.xpath('//input[@name="MD"]/@value')[0]
355 | url = doc.xpath("//form/@action")[0]
356 | break
357 | except Exception as e:
358 | self.status_signal.emit({"msg":"Error Authorizing Card (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
359 | time.sleep(self.error_delay)
360 | headers = {
361 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
362 | "Accept-Encoding": "gzip, deflate, br",
363 | "Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
364 | "Cache-Control": "max-age=0",
365 | "Connection": "keep-alive",
366 | "Content-Type": "application/x-www-form-urlencoded",
367 | "Host": "secure4.arcot.com",
368 | "Origin": "https://1eaf.cardinalcommerce.com",
369 | "Referer": "https://1eaf.cardinalcommerce.com/",
370 | "Upgrade-Insecure-Requests": "1",
371 | "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
372 | }
373 | body = {
374 | "PaReq": pa_req,
375 | "TermUrl": term_url,
376 | "MD": md
377 | }
378 | while True:
379 | self.status_signal.emit({"msg":"Authorizing Card (3)","status":"normal"})
380 | try:
381 | r = self.session.post(url,data=body,headers=headers)
382 | doc = lxml.html.fromstring(r.text)
383 | pa_res = doc.xpath('//input[@name="PaRes"]/@value')[0]
384 | pa_req = doc.xpath('//input[@name="PaReq"]/@value')[0]
385 | md = doc.xpath('//input[@name="MD"]/@value')[0]
386 | device_id = doc.xpath('//input[@name="DeviceID"]/@value')[0]
387 | locale = doc.xpath('//input[@name="locale"]/@value')[0]
388 | ABSlog = doc.xpath('//input[@name="ABSlog"]/@value')[0]
389 | device_DNA = doc.xpath('//input[@name="deviceDNA"]/@value')[0]
390 | execution_time = doc.xpath('//input[@name="executionTime"]/@value')[0]
391 | dna_error = doc.xpath('//input[@name="dnaError"]/@value')[0]
392 | mesc = doc.xpath('//input[@name="mesc"]/@value')[0]
393 | mesc_iteration_count = doc.xpath('//input[@name="mescIterationCount"]/@value')[0]
394 | desc = doc.xpath('//input[@name="desc"]/@value')[0]
395 | is_DNA_done = doc.xpath('//input[@name="isDNADone"]/@value')[0]
396 | arcot_flash_cookie = doc.xpath('//input[@name="arcotFlashCookie"]/@value')[0]
397 | url = doc.xpath("//form/@action")[0]
398 | break
399 | except Exception as e:
400 | self.status_signal.emit({"msg":"Error Authorizing Card (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
401 | time.sleep(self.error_delay)
402 |
403 | headers = {
404 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
405 | "Accept-Encoding": "gzip, deflate, br",
406 | "Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
407 | "Cache-Control": "max-age=0",
408 | "Connection": "keep-alive",
409 | "Content-Type": "application/x-www-form-urlencoded",
410 | "Host": "1eaf.cardinalcommerce.com",
411 | "Origin": "https://secure4.arcot.com",
412 | "Referer": "https://secure4.arcot.com/",
413 | "Upgrade-Insecure-Requests": "1",
414 | "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
415 | }
416 | body = {
417 | "PaRes": pa_res,
418 | "PaReq": pa_req,
419 | "MD": md,
420 | "DeviceID": device_id,
421 | "locale": locale,
422 | "ABSlog": ABSlog,
423 | "deviceDNA": device_DNA,
424 | "executionTime": execution_time,
425 | "dnaError": dna_error,
426 | "mesc": mesc,
427 | "mescIterationCount": mesc_iteration_count,
428 | "desc": desc,
429 | "isDNADone": is_DNA_done
430 | }
431 | while True:
432 | self.status_signal.emit({"msg":"Authorizing Card (4)","status":"normal"})
433 | try:
434 | r = self.session.post(url,data=body,headers=headers)
435 | doc = lxml.html.fromstring(r.text)
436 | pa_res = doc.xpath('//input[@name="PaRes"]/@value')[0]
437 | md = doc.xpath('//input[@name="MD"]/@value')[0]
438 | url = doc.xpath("//form/@action")[0]
439 | break
440 | except Exception as e:
441 | self.status_signal.emit({"msg":"Error Authorizing Card (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
442 | time.sleep(self.error_delay)
443 | headers = {
444 | "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
445 | "accept-encoding": "gzip, deflate, br",
446 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
447 | "cache-control": "max-age=0",
448 | "content-type": "application/x-www-form-urlencoded",
449 | "origin": "https://1eaf.cardinalcommerce.com",
450 | "referer": "https://1eaf.cardinalcommerce.com/",
451 | "upgrade-insecure-requests": "1",
452 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
453 | }
454 | body = {
455 | "PaRes": pa_res,
456 | "MD": md
457 | }
458 | while True:
459 | self.status_signal.emit({"msg":"Authorizing Card (5)","status":"normal"})
460 | try:
461 | r = self.session.post(url,data=body,headers=headers)
462 | jwt = r.text.split('parent.postMessage("')[1].split('"')[0]
463 | break
464 | except Exception as e:
465 | self.status_signal.emit({"msg":"Error Authorizing Card (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
466 | time.sleep(self.error_delay)
467 | headers = {
468 | "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
469 | "accept-encoding": "gzip, deflate, br",
470 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
471 | "cache-control": "max-age=0",
472 | "content-type": "application/x-www-form-urlencoded",
473 | "origin": "https://centinelapi.cardinalcommerce.com",
474 | "referer": "https://centinelapi.cardinalcommerce.com/V2/Cruise/StepUp",
475 | "upgrade-insecure-requests": "1",
476 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
477 | }
478 | body = {
479 | "McsId": md,
480 | "CardinalJWT": jwt,
481 | "Error": ""
482 | }
483 | while True:
484 | self.status_signal.emit({"msg":"Authorizing Card (6)","status":"normal"})
485 | try:
486 | r = self.session.post("https://centinelapi.cardinalcommerce.com/V1/Cruise/TermRedirection",data=body,headers=headers)
487 | doc = lxml.html.fromstring(r.text)
488 | transaction_id = doc.xpath('//input[@name="TransactionId"]/@value')[0]
489 | # url = doc.xpath("//form/@action")[0]
490 | return transaction_id
491 | except Exception as e:
492 | self.status_signal.emit({"msg":"Error Authorizing Card (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
493 | time.sleep(self.error_delay)
494 |
495 | def submit_card(self,transaction_id):
496 | headers = {
497 | "accept": "application/json, text/javascript, */*; q=0.01",
498 | "accept-encoding": "gzip, deflate, br",
499 | "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
500 | "content-type": "application/json",
501 | "origin": "https://www.bestbuy.com",
502 | "referer": "https://www.bestbuy.com/checkout/r/payment",
503 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36",
504 | "x-user-interface": "DotCom-Optimized",
505 | "x-native-checkout-version": "__VERSION__"
506 | }
507 | body = {"PaRes":"","orderId":self.order_id,"TransactionId":transaction_id}
508 | while True:
509 | self.status_signal.emit({"msg":"Submitting Card","status":"normal"})
510 | try:
511 | r = self.session.post("https://www.bestbuy.com/checkout/api/1.0/paysecure/submitCardAuthentication",json=body,headers=headers)
512 | if r.status_code == 200:
513 | return
514 | else:
515 | self.status_signal.emit({"msg":"Error Submitting Card","status":"error"})
516 | time.sleep(self.error_delay)
517 | except Exception as e:
518 | self.status_signal.emit({"msg":"Error Submitting Card (line {} {} {})".format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e),"status":"error"})
519 | time.sleep(self.error_delay)
520 |
521 |
522 |
523 |
--------------------------------------------------------------------------------
/sites/walmart_encryption.py:
--------------------------------------------------------------------------------
1 | __all__ = ['walmart_encryption']
2 |
3 | # Don't look below, you will not understand this Python code :) I don't.
4 |
5 | from js2py.pyjs import *
6 | # setting scope
7 | var = Scope( JS_BUILTINS )
8 | set_global_object(var)
9 |
10 | # Code follows:
11 | var.registers(['n', 'r', 'a', 'i', 'encrypt', 'o'])
12 | @Js
13 | def PyJsHoisted_encrypt_(e, t, PIE_L, PIE_E, PIE_K, PIE_key_id, PIE_phase, this, arguments, var=var):
14 | var = Scope({'e':e, 't':t, 'PIE_L':PIE_L, 'PIE_E':PIE_E, 'PIE_K':PIE_K, 'PIE_key_id':PIE_key_id, 'PIE_phase':PIE_phase, 'this':this, 'arguments':arguments}, var)
15 | var.registers(['PIE_L', 'PIE_K', 'l_var', 'PIE_key_id', 'p_var', 'i_var', 'PIE_E', 'u_var', 'PIE_phase', 'e', 'f_var', 'd_var', 'a_var', 't', 's_var', 'c_var'])
16 | var.put('PIE', Js({'L':var.get('parseInt')(var.get('PIE_L')),'E':var.get('parseInt')(var.get('PIE_E')),'K':var.get('PIE_K'),'key_id':var.get('PIE_key_id'),'phase':var.get('parseInt')(var.get('PIE_phase'))}))
17 | var.put('a_var', var.get('n').callprop('distill', var.get('e')))
18 | var.put('i_var', var.get('n').callprop('distill', var.get('t')))
19 | var.put('c_var', (var.get('a_var').callprop('substr', Js(0.0), var.get('PIE').get('L'))+var.get('a_var').callprop('substring', (var.get('a_var').get('length')-var.get('PIE').get('E')))))
20 | var.put('u_var', var.get('n').callprop('luhn', var.get('a_var')))
21 | var.put('s_var', var.get('a_var').callprop('substring', (var.get('PIE').get('L')+Js(1.0)), (var.get('a_var').get('length')-var.get('PIE').get('E'))))
22 | var.put('d_var', var.get('o').callprop('encrypt', (var.get('s_var')+var.get('i_var')), var.get('c_var'), var.get('PIE').get('K'), Js(10.0)))
23 | var.put('l_var', (((var.get('a_var').callprop('substr', Js(0.0), var.get('PIE').get('L'))+Js('0'))+var.get('d_var').callprop('substr', Js(0.0), (var.get('d_var').get('length')-var.get('i_var').get('length'))))+var.get('a_var').callprop('substring', (var.get('a_var').get('length')-var.get('PIE').get('E')))))
24 | var.put('f_var', var.get('n').callprop('reformat', var.get('n').callprop('fixluhn', var.get('l_var'), var.get('PIE').get('L'), var.get('u_var')), var.get('e')))
25 | var.put('p_var', var.get('n').callprop('reformat', var.get('d_var').callprop('substring', (var.get('d_var').get('length')-var.get('i_var').get('length'))), var.get('t')))
26 | return Js([var.get('f_var'), var.get('p_var'), var.get('n').callprop('integrity', var.get('PIE').get('K'), var.get('f_var'), var.get('p_var'))])
27 | PyJsHoisted_encrypt_.func_name = 'encrypt'
28 | var.put('encrypt', PyJsHoisted_encrypt_)
29 | var.put('n', Js({}))
30 | def PyJs_LONG_6_(var=var):
31 | @Js
32 | def PyJs_anonymous_0_(e, this, arguments, var=var):
33 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
34 | var.registers(['t', 'n', 'e', 'r'])
35 | #for JS loop
36 | var.put('t', (var.get('e').get('length')-Js(1.0)))
37 | var.put('n', Js(0.0))
38 | while (var.get('t')>=Js(0.0)):
39 | PyJsComma(var.put('n', var.get('parseInt')(var.get('e').callprop('substr', var.get('t'), Js(1.0)), Js(10.0)), '+'),var.put('t', Js(2.0), '-'))
40 |
41 | #for JS loop
42 | var.put('t', (var.get('e').get('length')-Js(2.0)))
43 | while (var.get('t')>=Js(0.0)):
44 | var.put('r', (Js(2.0)*var.get('parseInt')(var.get('e').callprop('substr', var.get('t'), Js(1.0)), Js(10.0))))
45 | PyJsComma(var.put('n', (var.get('r') if (var.get('r')=Js(0.0)) and var.put('t', var.get('e').callprop('substr', var.get('r'), Js(1.0)), '+'))
68 | finally:
69 | var.put('r',Js(var.get('r').to_number())+Js(1))
70 | return var.get('t')
71 | PyJs_anonymous_3_._set_name('anonymous')
72 | @Js
73 | def PyJs_anonymous_4_(e, t, this, arguments, var=var):
74 | var = Scope({'e':e, 't':t, 'this':this, 'arguments':arguments}, var)
75 | var.registers(['r', 'a', 'i', 'e', 't'])
76 | #for JS loop
77 | var.put('r', Js(''))
78 | var.put('a', Js(0.0))
79 | var.put('i', Js(0.0))
80 | while (var.get('i')=Js(0.0))) else var.put('r', var.get('t').callprop('substr', var.get('i'), Js(1.0)), '+'))
83 | finally:
84 | var.put('i',Js(var.get('i').to_number())+Js(1))
85 | return var.get('r')
86 | PyJs_anonymous_4_._set_name('anonymous')
87 | @Js
88 | def PyJs_anonymous_5_(e, t, n, this, arguments, var=var):
89 | var = Scope({'e':e, 't':t, 'n':n, 'this':this, 'arguments':arguments}, var)
90 | var.registers(['n', 'c', 'u', 'e', 's', 't', 'o'])
91 | var.put('o', (((((var.get('String').callprop('fromCharCode', Js(0.0))+var.get('String').callprop('fromCharCode', var.get('t').get('length')))+var.get('t'))+var.get('String').callprop('fromCharCode', Js(0.0)))+var.get('String').callprop('fromCharCode', var.get('n').get('length')))+var.get('n')))
92 | var.put('c', var.get('a').callprop('HexToWords', var.get('e')))
93 | var.get('c').put('3', Js(1.0), '^')
94 | var.put('u', var.get('r').get('cipher').get('aes').create(var.get('c')))
95 | var.put('s', var.get('i').callprop('compute', var.get('u'), var.get('o')))
96 | return (var.get('a').callprop('WordToHex', var.get('s').get('0'))+var.get('a').callprop('WordToHex', var.get('s').get('1')))
97 | PyJs_anonymous_5_._set_name('anonymous')
98 | return PyJsComma(PyJsComma(PyJsComma(PyJsComma(PyJsComma(PyJsComma(var.get('n').put('base10', Js('0123456789')),var.get('n').put('base62', Js('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'))),var.get('n').put('luhn', PyJs_anonymous_0_)),var.get('n').put('fixluhn', PyJs_anonymous_1_)),var.get('n').put('distill', PyJs_anonymous_3_)),var.get('n').put('reformat', PyJs_anonymous_4_)),var.get('n').put('integrity', PyJs_anonymous_5_))
99 | PyJs_LONG_6_()
100 | @Js
101 | def PyJs_anonymous_7_(e, this, arguments, var=var):
102 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
103 | var.registers(['e'])
104 | @Js
105 | def PyJs_anonymous_8_(this, arguments, var=var):
106 | var = Scope({'this':this, 'arguments':arguments}, var)
107 | var.registers([])
108 | return (Js('CORRUPT: ')+var.get(u"this").get('message'))
109 | PyJs_anonymous_8_._set_name('anonymous')
110 | PyJsComma(var.get(u"this").put('toString', PyJs_anonymous_8_),var.get(u"this").put('message', var.get('e')))
111 | PyJs_anonymous_7_._set_name('anonymous')
112 | @Js
113 | def PyJs_anonymous_9_(e, this, arguments, var=var):
114 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
115 | var.registers(['e'])
116 | @Js
117 | def PyJs_anonymous_10_(this, arguments, var=var):
118 | var = Scope({'this':this, 'arguments':arguments}, var)
119 | var.registers([])
120 | return (Js('INVALID: ')+var.get(u"this").get('message'))
121 | PyJs_anonymous_10_._set_name('anonymous')
122 | PyJsComma(var.get(u"this").put('toString', PyJs_anonymous_10_),var.get(u"this").put('message', var.get('e')))
123 | PyJs_anonymous_9_._set_name('anonymous')
124 | @Js
125 | def PyJs_anonymous_11_(e, this, arguments, var=var):
126 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
127 | var.registers(['e'])
128 | @Js
129 | def PyJs_anonymous_12_(this, arguments, var=var):
130 | var = Scope({'this':this, 'arguments':arguments}, var)
131 | var.registers([])
132 | return (Js('BUG: ')+var.get(u"this").get('message'))
133 | PyJs_anonymous_12_._set_name('anonymous')
134 | PyJsComma(var.get(u"this").put('toString', PyJs_anonymous_12_),var.get(u"this").put('message', var.get('e')))
135 | PyJs_anonymous_11_._set_name('anonymous')
136 | var.put('r', Js({'cipher':Js({}),'hash':Js({}),'mode':Js({}),'misc':Js({}),'codec':Js({}),'exception':Js({'corrupt':PyJs_anonymous_7_,'invalid':PyJs_anonymous_9_,'bug':PyJs_anonymous_11_})}))
137 | @Js
138 | def PyJs_anonymous_13_(e, this, arguments, var=var):
139 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
140 | var.registers(['n', 'd', 'c', 'a', 'u', 'i', 'e', 's', 't', 'o'])
141 | (var.get(u"this").get('_tables').get('0').get('0').get('0') or var.get(u"this").callprop('_precompute'))
142 | var.put('c', var.get(u"this").get('_tables').get('0').get('4'))
143 | var.put('u', var.get(u"this").get('_tables').get('1'))
144 | var.put('s', var.get('e').get('length'))
145 | var.put('d', Js(1.0))
146 | if ((PyJsStrictNeq(Js(4.0),var.get('s')) and PyJsStrictNeq(Js(6.0),var.get('s'))) and PyJsStrictNeq(Js(8.0),var.get('s'))):
147 | PyJsTempException = JsToPyException(var.get('r').get('exception').get('invalid').create(Js('invalid aes key size')))
148 | raise PyJsTempException
149 | #for JS loop
150 | PyJsComma(var.get(u"this").put('_key', Js([var.put('i', var.get('e').callprop('slice', Js(0.0))), var.put('o', Js([]))])),var.put('t', var.get('s')))
151 | while (var.get('t')<((Js(4.0)*var.get('s'))+Js(28.0))):
152 | try:
153 | def PyJs_LONG_14_(var=var):
154 | return PyJsComma(var.put('a', ((((var.get('c').get(PyJsBshift(var.get('a'),Js(24.0)))<>Js(16.0))&Js(255.0)))<>Js(8.0))&Js(255.0)))<>Js(7.0))))))))
155 | PyJsComma(PyJsComma(var.put('a', var.get('i').get((var.get('t')-Js(1.0)))),((((var.get('t')%var.get('s'))==Js(0.0)) or (PyJsStrictEq(Js(8.0),var.get('s')) and ((var.get('t')%var.get('s'))==Js(4.0)))) and PyJs_LONG_14_())),var.get('i').put(var.get('t'), (var.get('i').get((var.get('t')-var.get('s')))^var.get('a'))))
156 | finally:
157 | (var.put('t',Js(var.get('t').to_number())+Js(1))-Js(1))
158 | #for JS loop
159 | var.put('n', Js(0.0))
160 | while var.get('t'):
161 | try:
162 | def PyJs_LONG_15_(var=var):
163 | return var.get('o').put(var.get('n'), (var.get('a') if ((var.get('t')<=Js(4.0)) or (var.get('n')>Js(16.0))&Js(255.0)))))^var.get('u').get('2').get(var.get('c').get(((var.get('a')>>Js(8.0))&Js(255.0)))))^var.get('u').get('3').get(var.get('c').get((Js(255.0)&var.get('a')))))))
164 | PyJsComma(var.put('a', var.get('i').get((var.get('t') if (Js(3.0)&var.get('n')) else (var.get('t')-Js(4.0))))),PyJs_LONG_15_())
165 | finally:
166 | PyJsComma((var.put('n',Js(var.get('n').to_number())+Js(1))-Js(1)),(var.put('t',Js(var.get('t').to_number())-Js(1))+Js(1)))
167 | PyJs_anonymous_13_._set_name('anonymous')
168 | @Js
169 | def PyJs_anonymous_16_(e, this, arguments, var=var):
170 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
171 | var.registers(['e'])
172 | return var.get(u"this").callprop('_crypt', var.get('e'), Js(0.0))
173 | PyJs_anonymous_16_._set_name('anonymous')
174 | @Js
175 | def PyJs_anonymous_17_(e, this, arguments, var=var):
176 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
177 | var.registers(['e'])
178 | return var.get(u"this").callprop('_crypt', var.get('e'), Js(1.0))
179 | PyJs_anonymous_17_._set_name('anonymous')
180 | @Js
181 | def PyJs_anonymous_18_(this, arguments, var=var):
182 | var = Scope({'this':this, 'arguments':arguments}, var)
183 | var.registers(['l', 'n', 'd', 'p', 'r', 'c', 'a', 'u', 'i', 'f', 'e', 's', 't', 'o'])
184 | var.put('u', var.get(u"this").get('_tables').get('0'))
185 | var.put('s', var.get(u"this").get('_tables').get('1'))
186 | var.put('d', var.get('u').get('4'))
187 | var.put('l', var.get('s').get('4'))
188 | var.put('f', Js([]))
189 | var.put('p', Js([]))
190 | #for JS loop
191 | var.put('e', Js(0.0))
192 | while (var.get('e')>Js(7.0)))))^var.get('e')), var.get('e'))
195 | finally:
196 | (var.put('e',Js(var.get('e').to_number())+Js(1))-Js(1))
197 | #for JS loop
198 | var.put('t', var.put('n', Js(0.0)))
199 | while var.get('d').get(var.get('t')).neg():
200 | try:
201 | #for JS loop
202 | def PyJs_LONG_19_(var=var):
203 | return PyJsComma(PyJsComma(PyJsComma(PyJsComma(PyJsComma(var.put('i', (((var.put('i', ((((var.get('n')^(var.get('n')<>Js(8.0))^(Js(255.0)&var.get('i')))^Js(99.0))),var.get('d').put(var.get('t'), var.get('i'))),var.get('l').put(var.get('i'), var.get('t'))),var.put('c', ((((Js(16843009.0)*var.get('f').get(var.put('a', var.get('f').get(var.put('r', var.get('f').get(var.get('t')))))))^(Js(65537.0)*var.get('a')))^(Js(257.0)*var.get('r')))^(Js(16843008.0)*var.get('t'))))),var.put('o', ((Js(257.0)*var.get('f').get(var.get('i')))^(Js(16843008.0)*var.get('i'))))),var.put('e', Js(0.0)))
204 | PyJs_LONG_19_()
205 | while (var.get('e')>Js(16.0))&Js(255.0))))^var.get('y').get(((var.get('d')>>Js(8.0))&Js(255.0))))^var.get('E').get((Js(255.0)&var.get('l'))))^var.get('c').get(var.get('p')))),var.put('a', ((((var.get('b').get(PyJsBshift(var.get('s'),Js(24.0)))^var.get('v').get(((var.get('d')>>Js(16.0))&Js(255.0))))^var.get('y').get(((var.get('l')>>Js(8.0))&Js(255.0))))^var.get('E').get((Js(255.0)&var.get('u'))))^var.get('c').get((var.get('p')+Js(1.0)))))),var.put('i', ((((var.get('b').get(PyJsBshift(var.get('d'),Js(24.0)))^var.get('v').get(((var.get('l')>>Js(16.0))&Js(255.0))))^var.get('y').get(((var.get('u')>>Js(8.0))&Js(255.0))))^var.get('E').get((Js(255.0)&var.get('s'))))^var.get('c').get((var.get('p')+Js(2.0)))))),var.put('l', ((((var.get('b').get(PyJsBshift(var.get('l'),Js(24.0)))^var.get('v').get(((var.get('u')>>Js(16.0))&Js(255.0))))^var.get('y').get(((var.get('s')>>Js(8.0))&Js(255.0))))^var.get('E').get((Js(255.0)&var.get('d'))))^var.get('c').get((var.get('p')+Js(3.0)))))),var.put('p', Js(4.0), '+')),var.put('u', var.get('n'))),var.put('s', var.get('a'))),var.put('d', var.get('i')))
247 | PyJs_LONG_21_()
248 | finally:
249 | (var.put('o',Js(var.get('o').to_number())+Js(1))-Js(1))
250 | #for JS loop
251 | var.put('o', Js(0.0))
252 | while (var.get('o')>Js(16.0))&Js(255.0)))<>Js(8.0))&Js(255.0)))<Js(0.0)):
292 | PyJsComma(var.put('t', Js(4.0), '-'),var.put('n', var.get('a').get('Hex').callprop('substr', (PyJsBshift(var.get('e'),var.get('t'))&Js(15.0)), Js(1.0)), '+'))
293 |
294 | return var.get('n')
295 | PyJs_anonymous_25_._set_name('anonymous')
296 | var.put('a', Js({'HexToKey':PyJs_anonymous_23_,'HexToWords':PyJs_anonymous_24_,'Hex':Js('0123456789abcdef'),'WordToHex':PyJs_anonymous_25_}))
297 | var.put('i', Js({}))
298 | @Js
299 | def PyJs_anonymous_26_(e, this, arguments, var=var):
300 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
301 | var.registers(['e'])
302 | return (Js(2147483647.0)!=(Js(2147483647.0)|var.get('e')))
303 | PyJs_anonymous_26_._set_name('anonymous')
304 | @Js
305 | def PyJs_anonymous_27_(e, this, arguments, var=var):
306 | var = Scope({'e':e, 'this':this, 'arguments':arguments}, var)
307 | var.registers(['e'])
308 | def PyJs_LONG_28_(var=var):
309 | return PyJsComma(PyJsComma(PyJsComma(var.get('e').put('0', (((Js(2147483647.0)&var.get('e').get('0'))<>Js(2.0))&Js(3.0)), ((Js(255.0)&var.get('t').callprop('charCodeAt', var.get('o')))<<(Js(8.0)*(Js(3.0)-(Js(3.0)&var.get('o'))))), '^'),(((Js(0.0)==(Js(15.0)&var.put('o',Js(var.get('o').to_number())+Js(1)))) and (var.get('o')>Js(2.0))&Js(3.0)), (Js(128.0)<<(Js(8.0)*(Js(3.0)-(Js(3.0)&var.get('o'))))), '^')))
327 | return PyJsComma(PyJsComma(PyJsComma(PyJsComma(PyJsComma(PyJs_LONG_30_(),var.get('n').put('0', var.get('r').get('0'), '^')),var.get('n').put('1', var.get('r').get('1'), '^')),var.get('n').put('2', var.get('r').get('2'), '^')),var.get('n').put('3', var.get('r').get('3'), '^')),var.get('e').callprop('encrypt', var.get('n')))
328 | PyJs_anonymous_29_._set_name('anonymous')
329 | PyJsComma(PyJsComma(PyJsComma(var.get('i').put('MSBnotZero', PyJs_anonymous_26_),var.get('i').put('leftShift', PyJs_anonymous_27_)),var.get('i').put('const_Rb', Js(135.0))),var.get('i').put('compute', PyJs_anonymous_29_))
330 | @Js
331 | def PyJs_anonymous_31_(e, t, n, r, this, arguments, var=var):
332 | var = Scope({'e':e, 't':t, 'n':n, 'r':r, 'this':this, 'arguments':arguments}, var)
333 | var.registers(['n', 'r', 'a', 'i', 'e', 't'])
334 | var.put('a', var.get('Array').create(Js(4.0)))
335 | var.put('i', var.get('n').get('length'))
336 | def PyJs_LONG_32_(var=var):
337 | return PyJsComma(PyJsComma(PyJsComma(PyJsComma(var.get('a').put('0', (Js(16908544.0)|((var.get('r')>>Js(16.0))&Js(255.0)))),var.get('a').put('1', ((((((var.get('r')>>Js(8.0))&Js(255.0))<Js(0.0)):
349 | PyJsComma(var.put('n',Js(var.get('n').to_number())-Js(1)),((var.put('a', var.get('e'), '*')>=Js(256.0)) and PyJsComma(var.put('a', Js(256.0), '/'),var.put('r',Js(var.get('r').to_number())+Js(1)))))
350 |
351 | return PyJsComma(((var.get('a')>Js(1.0)) and var.put('r',Js(var.get('r').to_number())+Js(1))),var.get('r'))
352 | PyJs_anonymous_33_._set_name('anonymous')
353 | @Js
354 | def PyJs_anonymous_34_(e, t, n, this, arguments, var=var):
355 | var = Scope({'e':e, 't':t, 'n':n, 'this':this, 'arguments':arguments}, var)
356 | var.registers(['n', 'r', 'a', 'i', 'e', 't'])
357 | var.put('a', Js(0.0))
358 | #for JS loop
359 | var.put('r', (var.get('e').get('length')-Js(1.0)))
360 | while (var.get('r')>=Js(0.0)):
361 | try:
362 | var.put('i', ((var.get('e').get(var.get('r'))*var.get('n'))+var.get('a')))
363 | PyJsComma(var.get('e').put(var.get('r'), (var.get('i')%var.get('t'))),var.put('a', ((var.get('i')-var.get('e').get(var.get('r')))/var.get('t'))))
364 | finally:
365 | var.put('r',Js(var.get('r').to_number())-Js(1))
366 | PyJs_anonymous_34_._set_name('anonymous')
367 | @Js
368 | def PyJs_anonymous_35_(e, t, n, this, arguments, var=var):
369 | var = Scope({'e':e, 't':t, 'n':n, 'this':this, 'arguments':arguments}, var)
370 | var.registers(['n', 'r', 'a', 'i', 'e', 't'])
371 | #for JS loop
372 | var.put('r', (var.get('e').get('length')-Js(1.0)))
373 | var.put('a', var.get('n'))
374 | while ((var.get('r')>=Js(0.0)) and (var.get('a')>Js(0.0))):
375 | var.put('i', (var.get('e').get(var.get('r'))+var.get('a')))
376 | PyJsComma(PyJsComma(var.get('e').put(var.get('r'), (var.get('i')%var.get('t'))),var.put('a', ((var.get('i')-var.get('e').get(var.get('r')))/var.get('t')))),var.put('r',Js(var.get('r').to_number())-Js(1)))
377 |
378 | PyJs_anonymous_35_._set_name('anonymous')
379 | @Js
380 | def PyJs_anonymous_36_(e, t, n, r, a, this, arguments, var=var):
381 | var = Scope({'e':e, 't':t, 'n':n, 'r':r, 'a':a, 'this':this, 'arguments':arguments}, var)
382 | var.registers(['n', 'r', 'c', 'a', 'u', 'i', 'e', 't'])
383 | var.put('c', var.get('Array').create(var.get('r')))
384 | #for JS loop
385 | var.put('i', Js(0.0))
386 | while (var.get('i')Js(0.0)) and var.put('l', (Js(16.0)-var.get('l'))))
433 | var.put('p', var.get('Array').create((((var.get('n').get('length')+var.get('l'))+var.get('s'))+Js(1.0))))
434 | #for JS loop
435 | var.put('f', Js(0.0))
436 | while (var.get('f')Js(0.0)) and (Js(0.0)==(Js(3.0)&var.get('f')))) and PyJsComma(PyJsComma(var.put('b', ((var.get('f')>>Js(2.0))&Js(255.0))),var.put('b', (((var.get('b')<=Js(0.0)):
541 | try:
542 | (PyJsComma(var.get('s').put(var.get('m'), var.get('h')),var.put('f', Js(0.0))) if (var.put('h', ((var.get('s').get(var.get('m'))+var.get('p').get(var.get('m')))+var.get('f')))=Js(0.0)):
550 | try:
551 | pass
552 | (PyJsComma(var.get('d').put(var.get('m'), var.get('h')),var.put('f', Js(0.0))) if (var.put('h', ((var.get('d').get(var.get('m'))+var.get('p').get(var.get('m')))+var.get('f')))