Skip to content

Commit 7972b1e

Browse files
committed
update scripts
1 parent 1e253f5 commit 7972b1e

File tree

6 files changed

+382
-4
lines changed

6 files changed

+382
-4
lines changed

gettoken.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import os
2+
import time
3+
from datetime import datetime
4+
from playwright.sync_api import sync_playwright
5+
# from dotenv import load_dotenv
6+
import logging
7+
import random
8+
import time
9+
from playwright_stealth import stealth_sync
10+
import logging
11+
import re
12+
import sys
13+
import argparse
14+
import json
15+
current = os.path.dirname(os.path.realpath(__file__))
16+
parent = os.path.dirname(current)
17+
sys.path.append(parent)
18+
from settings import CLOSE_MESSAGE, CHROME_USER_DATA, CONTINUE_MESSAGE
19+
20+
21+
22+
def intercept_request(request):
23+
# print(request.url)
24+
# we can update requests with custom headers
25+
if "config" in request.url :
26+
breakpoint()
27+
print(request.headers['x-resy-auth-token'])
28+
# request.headers['x-secret-token'] = "123"
29+
# print("patched headers of a secret request")
30+
# # or adjust sent data
31+
# if request.method == "POST":
32+
# request.post_data = "patched"
33+
# print("patched POST request")
34+
return request
35+
36+
37+
user_agents = [
38+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
39+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15",
40+
"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
41+
# 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0'
42+
# More user agents can be added here
43+
]
44+
45+
46+
chrome_user_data = f"{CHROME_USER_DATA}\\Profile3"
47+
user_agent = random.choice(user_agents)
48+
with sync_playwright() as pr:
49+
wargs = []
50+
# wargs.append('--enable-logging=stderr')
51+
# list chromium arguments: https://peter.sh/experiments/chromium-command-line-switches/
52+
wargs.append('--v=1')
53+
wargs.append('--no-sandbox')
54+
wargs.append('--enable-features=NetworkService,NetworkServiceInProcess')
55+
wargs.append('--enable-automation')
56+
wargs.append('--disable-popup-blocking')
57+
wargs.append('--disable-web-security')
58+
wargs.append('--start-maximized')
59+
60+
wargs.append('--disable-fetching-hints-at-navigation-start')
61+
wargs.append('--force-first-run')
62+
wargs.append('--content-shell-hide-toolbar')
63+
wargs.append('--suppress-message-center-popups')
64+
wargs.append('--no-first-run')
65+
wargs.append('--force-show-update-menu-badge')
66+
67+
68+
# browser = pr.chromium.launch(headless=headless, args=wargs)
69+
# breakpoint()
70+
# proxy_server = "http://kpeqkzlp:[email protected]:5868"
71+
browser = pr.chromium.launch_persistent_context(user_data_dir=chrome_user_data,
72+
headless=True,
73+
args=wargs,
74+
user_agent=user_agent,
75+
permissions=['geolocation', 'notifications'],
76+
java_script_enabled=True,
77+
no_viewport=True,
78+
)
79+
80+
81+
page = browser.pages[0]
82+
stealth_sync(page)
83+
# page.on("request", lambda msg: logging.debug(f"PAGE LOG: {msg.text}"))
84+
page.on("request", intercept_request)
85+
page.goto("https://resy.com", wait_until='domcontentloaded')
86+
breakpoint()
87+
88+
89+
90+
# def main():
91+
# parser = argparse.ArgumentParser(description="Resy Bot v2")
92+
# parser.add_argument('-cp', '--chprofile', type=str,help="Chrome Profile Name")
93+
# args = parser.parse_args()
94+
95+
# chprofile = args.chprofile
96+
97+
# user_agents = [
98+
# "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
99+
# "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15",
100+
# "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
101+
# # 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0'
102+
# # More user agents can be added here
103+
# ]
104+
# chrome_user_data = f"{CHROME_USER_DATA}\\{chprofile}"
105+
# try:
106+
# user_agent = random.choice(user_agents)
107+
# with sync_playwright() as pr:
108+
# wargs = []
109+
# # wargs.append('--enable-logging=stderr')
110+
# # list chromium arguments: https://peter.sh/experiments/chromium-command-line-switches/
111+
# wargs.append('--v=1')
112+
# wargs.append('--no-sandbox')
113+
# wargs.append('--enable-features=NetworkService,NetworkServiceInProcess')
114+
# wargs.append('--enable-automation')
115+
# wargs.append('--disable-popup-blocking')
116+
# wargs.append('--disable-web-security')
117+
# wargs.append('--start-maximized')
118+
119+
# wargs.append('--disable-fetching-hints-at-navigation-start')
120+
# wargs.append('--force-first-run')
121+
# wargs.append('--content-shell-hide-toolbar')
122+
# wargs.append('--suppress-message-center-popups')
123+
# wargs.append('--no-first-run')
124+
# wargs.append('--force-show-update-menu-badge')
125+
126+
127+
# # browser = pr.chromium.launch(headless=headless, args=wargs)
128+
# # breakpoint()
129+
# proxy_server = "http://kpeqkzlp:[email protected]:5868"
130+
# browser = pr.chromium.launch_persistent_context(user_data_dir=chrome_user_data,
131+
# headless=True,
132+
# args=wargs,
133+
# user_agent=user_agent,
134+
# permissions=['geolocation', 'notifications'],
135+
# java_script_enabled=True,
136+
# no_viewport=True,
137+
# )
138+
139+
140+
# page = browser.pages[0]
141+
# stealth_sync(page)
142+
# page.goto("https://resy.com", wait_until='domcontentloaded')
143+
# breakpoint()
144+
# except:
145+
# pass
146+
147+
148+
# if __name__ == '__main__':
149+
# main()

h1.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ResyConfig
2+
ResyConfig specifies credentials for personal Resy accounts. Users should create a credentials.json file formatted as:
3+
4+
{
5+
"api_key": "<api-key>",
6+
"token": "<api-token>",
7+
"payment_method_id": <payment-method>,
8+
"email": "<email>",
9+
"password": "<password>"
10+
}
11+
These values can be found in requests made in the Network tab.
12+
13+
api_key can be found in the request headers under the key Authorization in the format ResyAPI api_key="<api-key>"
14+
token can be found in the request headers under the key X-Resy-Auth-Token
15+
payment_method_id can be found in the request body to the endpoint /3/book

main.py

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,8 @@ def __init__(self) -> None:
9494
mainFrame.grid(column=0, row=0, sticky=(N, E, W, S), columnspan=4)
9595

9696
def gitPull(self):
97-
# g = git.cmd.Git(os.getcwd())
9897
self.gitme.pull()
99-
# g.pull()
98+
run_module(comlist=[PIPLOC, "-r", "requirements.txt"])
10099
messagebox.showinfo(title='Info', message='the scripts has updated, reopen the application...')
101100
sys.exit()
102101

@@ -143,7 +142,8 @@ def __init__(self, window) -> None:
143142
reservationlistButton = FrameButton(self, window, text="Update Reservation Type", class_frame=AddReservationFrame)
144143
periodlistButton = FrameButton(self, window, text="Update Period", class_frame=AddPeriodFrame)
145144
chromiumProfileButton = FrameButton(self, window, text="Update Chromium Profile", class_frame=ChromiumProfileFrame)
146-
setupChromiumButton = FrameButton(self, window, text="Chromium Profile Tester", class_frame=SetupChromiumFrame)
145+
# setupChromiumButton = FrameButton(self, window, text="Chromium Profile Tester", class_frame=SetupChromiumFrame)
146+
UpdateTokenButton = FrameButton(self, window, text="Update Profile Token", class_frame=UpdateTokenFrame)
147147

148148

149149
# # # layout
@@ -154,7 +154,8 @@ def __init__(self, window) -> None:
154154
reservationlistButton.grid(column = 0, row = 4, sticky=(W, E, N, S), padx=15, pady=5, columnspan=3)
155155
periodlistButton.grid(column = 0, row = 5, sticky=(W, E, N, S), padx=15, pady=5, columnspan=3)
156156
chromiumProfileButton.grid(column = 0, row = 6, sticky=(W, E, N, S), padx=15, pady=5, columnspan=3)
157-
setupChromiumButton.grid(column = 0, row = 7, sticky=(W, E, N, S), padx=15, pady=5, columnspan=3)
157+
# setupChromiumButton.grid(column = 0, row = 7, sticky=(W, E, N, S), padx=15, pady=5, columnspan=3)
158+
UpdateTokenButton.grid(column = 0, row = 7, sticky=(W, E, N, S), padx=15, pady=5, columnspan=3)
158159

159160
class AddReservationFrame(ttk.Frame):
160161
def __init__(self, window) -> None:
@@ -399,6 +400,50 @@ def chromeTester(self, profile):
399400
profileselected = [value for value in profilelisttmp if value['profilename']==profile]
400401
run_module(comlist=[PYLOC, "modules/chromium_setup.py", "-cp", profile, "-em", profileselected[0]['email'], "-pw", profileselected[0]['password'] ])
401402

403+
class UpdateTokenFrame(ttk.Frame):
404+
def __init__(self, window) -> None:
405+
super().__init__(window)
406+
self.grid(column=0, row=0, sticky=(N, E, W, S), columnspan=4)
407+
self.config(padding="20 20 20 20", borderwidth=1, relief='groove')
408+
409+
self.columnconfigure(0, weight=1)
410+
self.columnconfigure(1, weight=1)
411+
self.columnconfigure(2, weight=1)
412+
# self.columnconfigure(3, weight=1)
413+
self.rowconfigure(0, weight=1)
414+
self.rowconfigure(1, weight=1)
415+
self.rowconfigure(2, weight=1)
416+
self.rowconfigure(3, weight=1)
417+
self.rowconfigure(4, weight=1)
418+
self.rowconfigure(5, weight=1)
419+
420+
titleLabel = TitleLabel(self, 'Update Token Profile')
421+
closeButton = CloseButton(self)
422+
file = open("profilelist.json", "r")
423+
profilelisttmp = json.load(file)
424+
profileList = []
425+
for text in [value['profilename'] for value in profilelisttmp]:
426+
profileList.append(ttk.Button(self, text=text, command=lambda pro=text:self.chromeTester(pro)))
427+
428+
# layout
429+
titleLabel.grid(column = 0, row = 0, sticky=(W, E, N, S), padx=15, pady=5, columnspan=4)
430+
closeButton.grid(column = 0, row = 6, sticky = (E, N, S), columnspan=4)
431+
432+
colnum = 0
433+
rownum = 1
434+
for profile in profileList:
435+
if colnum == 3:
436+
colnum = 0
437+
rownum += 1
438+
profile.grid(column = colnum, row = rownum, sticky=(W, E, N, S), padx=15, pady=5)
439+
colnum += 1
440+
441+
def chromeTester(self, profile):
442+
file = open("profilelist.json", "r")
443+
profilelisttmp = json.load(file)
444+
profileselected = [value for value in profilelisttmp if value['profilename']==profile]
445+
run_module(comlist=[PYLOC, "modules/update_token.py", "-cp", profile, "-em", profileselected[0]['email'], "-pw", profileselected[0]['password'] ])
446+
402447
class ListCommandFrame(ttk.Frame):
403448
def __init__(self, window) -> None:
404449
super().__init__(window)
@@ -857,7 +902,9 @@ def main():
857902
if __name__ == "__main__":
858903
if platform == "linux" or platform == "linux2":
859904
PYLOC = "python"
905+
PIPLOC = "pip"
860906
elif platform == "win32":
861907
PYLOC = PYTHON_EXE
908+
PIPLOC = os.getcwd() + os.sep + r"venv\Scripts\pip.exe"
862909

863910
main()

modules/update_token.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import os
2+
import time
3+
from datetime import datetime
4+
from playwright.sync_api import sync_playwright
5+
from dotenv import load_dotenv
6+
import logging
7+
import random
8+
import time
9+
from playwright_stealth import stealth_sync
10+
import logging
11+
import re
12+
import sys
13+
import argparse
14+
from subprocess import Popen, check_call
15+
from user_agent import generate_user_agent
16+
import json
17+
18+
current = os.path.dirname(os.path.realpath(__file__))
19+
parent = os.path.dirname(current)
20+
sys.path.append(parent)
21+
from settings import CLOSE_MESSAGE, CHROME_USER_DATA, CHROME_EXE
22+
def login_to_resy(page, email, password):
23+
"""Login to Resy with enhanced stability and error handling."""
24+
try:
25+
page.wait_for_selector('.AnnouncementModal__icon-close', timeout=5000)
26+
page.click('.AnnouncementModal__icon-close')
27+
except Exception:
28+
logging.info("No announcement modal to close.")
29+
# breakpoint()
30+
page.click("text=Log in", timeout=30000)
31+
page.click("text=Use Email and Password instead", timeout=30000)
32+
33+
page.fill('input[name="email"]', email)
34+
page.fill('input[name="password"]', password)
35+
36+
page.click('[name="login_form"] button', timeout=10000)
37+
page.evaluate("() => document.fonts.ready")
38+
39+
def random_delay(min_seconds, max_seconds):
40+
time.sleep(random.uniform(min_seconds, max_seconds))
41+
42+
def intercept_request(request, profilename):
43+
# print(request.url)
44+
# we can update requests with custom headers
45+
api_key = ''
46+
token = ''
47+
if "https://api.resy.com/2/config" in request.url:
48+
# print(request.url)
49+
# breakpoint()
50+
try:
51+
token = request.headers['x-resy-auth-token']
52+
api_key=str(request.headers['authorization']).replace('ResyAPI api_key=', "").replace('"','')
53+
# print(token, api_key)
54+
file = open("profilelist.json", "r")
55+
profilelist = json.load(file)
56+
tmplist = []
57+
for dl in profilelist:
58+
if dl['profilename'] == profilename:
59+
tmplist.append({"profilename": profilename, "email":dl['email'], "password": dl['password'], "api_key": api_key, "token":token})
60+
else:
61+
tmplist.append(dl)
62+
with open("profilelist.json", "w") as final:
63+
json.dump(tmplist, final)
64+
input("token Updated.. " + CLOSE_MESSAGE)
65+
sys.exit()
66+
except:
67+
return request
68+
# request.headers['x-secret-token'] = "123"
69+
# print("patched headers of a secret request")
70+
# # or adjust sent data
71+
# if request.method == "POST":
72+
# request.post_data = "patched"
73+
# print("patched POST request")
74+
# input(token + "\n" + api_key)
75+
return request
76+
77+
def main():
78+
# breakpoint()
79+
parser = argparse.ArgumentParser(description="Chromium Setup")
80+
parser.add_argument('-cp', '--chprofile', type=str,help="Chrome Profile Name")
81+
parser.add_argument('-em', '--email', type=str,help="Resy Email")
82+
parser.add_argument('-pw', '--password', type=str,help="Resy Password")
83+
args = parser.parse_args()
84+
85+
if not args.chprofile or not args.email or not args.password:
86+
input(" ".join(['Please add complete parameters, ex: python chromium_setup.py -cp [chrome_profile] -em [email] -pw [password]', CLOSE_MESSAGE]))
87+
sys.exit()
88+
89+
chrome_user_data = f"{CHROME_USER_DATA}\\{args.chprofile}"
90+
error = True
91+
try:
92+
# user_agent = random.choice(user_agents)
93+
with sync_playwright() as pr:
94+
wargs = []
95+
wargs.append('--v=1')
96+
wargs.append('--no-sandbox')
97+
wargs.append('--enable-features=NetworkService,NetworkServiceInProcess')
98+
wargs.append('--enable-automation')
99+
wargs.append('--disable-popup-blocking')
100+
wargs.append('--disable-web-security')
101+
wargs.append('--start-maximized')
102+
browser = pr.chromium.launch_persistent_context(user_data_dir=chrome_user_data,
103+
headless=True,
104+
args=wargs,
105+
user_agent=generate_user_agent(),
106+
permissions=['geolocation', 'notifications'],
107+
java_script_enabled=True,
108+
no_viewport=True
109+
)
110+
page = browser.pages[0]
111+
stealth_sync(page)
112+
# page.on("request", intercept_request)
113+
page.on("request", lambda request: intercept_request(request, profilename=args.chprofile))
114+
115+
# runButton = ttk.Button(self, text='Run Process', command = lambda:self.run_process(profile=chprofileentry, headless=headlessentry, exemode=procentry, nstop=nstopentry))
116+
117+
page.goto("https://resy.com", wait_until='domcontentloaded', timeout=20000)
118+
random_delay(2, 5)
119+
# breakpoint()
120+
if page.query_selector('button.Button--login'):
121+
login_to_resy(page, args.email, args.password)
122+
message = "Logged in successfully."
123+
logging.info(message)
124+
print(message)
125+
time.sleep(3)
126+
browser.close()
127+
error = False
128+
sys.exit()
129+
130+
except:
131+
if error:
132+
input("An error occurred..," + CLOSE_MESSAGE)
133+
sys.exit()
134+
if __name__ == '__main__':
135+
main()

requirements.txt

66 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)