Merge branch 'master' into feature/recaptha

This commit is contained in:
PAN Lei
2022-05-21 15:24:27 +02:00
12 changed files with 108 additions and 38 deletions
+1
View File
@@ -13,3 +13,4 @@ lib
appointment_*.log
./build
./dist
./contact_all.xlsx
+14
View File
@@ -0,0 +1,14 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.security.codesign</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>codesign</string>
<key>CFBundleVersion</key>
<string>0.3</string>
</dict>
</plist>
+18 -3
View File
@@ -8,10 +8,13 @@ KEY_START_NUMBER = "KEY_START_NUMBER"
KEY_END_NUMBER = "KEY_END_NUMBER"
KEY_MAX_WORKERS = "KEY_MAX_WORKERS"
KEY_RANDOM = "KEY_RANDOM"
KEY_PROXY_RES = "KEY_PROXY_RES"
KEY_PROXY_CC = "KEY_PROXY_CC"
KEY_FAUBOURG = "KEY_FAUBOURG"
KEY_GEORGE = "KEY_GEORGE"
KEY_SEVRES = "KEY_SEVRES"
GROUP_STORE = "STORE"
GROUP_PROXY = "GROUP_PROXY"
file_list_column = [
[sg.Text('请输入联系人表的起始和结束行')],
@@ -21,18 +24,24 @@ file_list_column = [
[sg.Submit(button_text="运行", key="submit")]
]
# For now will only show the name of the file that was chosen
settings_column = [
store_settings_column = [
[sg.Text("目标商店")],
[sg.Radio('随机', group_id=GROUP_STORE, key=KEY_RANDOM, default=True)],
[sg.Radio('Hermès Faubourg Saint-Honoré', group_id=GROUP_STORE, key=KEY_FAUBOURG, default=False)],
[sg.Radio('Hermès George V', group_id=GROUP_STORE, key=KEY_GEORGE, default=False)],
[sg.Radio('Hermès Sèvres', group_id=GROUP_STORE, key=KEY_SEVRES, default=False)]
]
proxy_settings_column = [
[sg.Text("代理ip池")],
[sg.Radio('res(速度)', group_id=GROUP_PROXY, key=KEY_PROXY_RES, default=True)],
[sg.Radio('cc(稳定)', group_id=GROUP_PROXY, key=KEY_PROXY_CC, default=False)],
]
# ----- Full layout -----
layout = [
[
sg.Column(file_list_column),
sg.Column(settings_column)
sg.Column(store_settings_column),
sg.Column(proxy_settings_column)
]
]
@@ -54,7 +63,13 @@ while True:
store_type = 2
elif values[KEY_SEVRES]:
store_type = 3
start_book(start_line, end_line, store_choose_state=store_type, max_workers=max_workers)
proxy_type = 0
if values[KEY_PROXY_CC]:
proxy_type = 1
elif values[KEY_PROXY_RES]:
proxy_type = 0
start_book(start_line, end_line, store_choose_state=store_type, max_workers=max_workers, proxy_type=proxy_type)
# except Exception as error:
# print("Not Integer: ")
# print(error)
+2 -3
View File
@@ -8,7 +8,7 @@ a = Analysis(
['appointment.py'],
pathex=[],
binaries=[],
datas=[],
datas=[('appointment.json','.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
@@ -49,7 +49,6 @@ coll = COLLECT(
name='appointment',
)
import shutil
shutil.copyfile('./appointment.json', '{0}/appointment.json'.format(DISTPATH))
shutil.copyfile('./contact_all.xlsx', '{0}/contact_all.xlsx'.format(DISTPATH))
shutil.copyfile('./config.ini', '{0}/config.ini'.format(DISTPATH))
shutil.copytree('./venv/site-packages/grpc/_cython/_credentials', '{0}/appointment/grpc/_cython/_credentials'.format(DISTPATH))
#shutil.copytree('./venv/Lib/site-packages/grpc/_cython/_credentials', '{0}/appointment/grpc/_cython/_credentials'.format(DISTPATH))
+1 -2
View File
@@ -8,7 +8,7 @@ a = Analysis(
['appointment.py'],
pathex=[],
binaries=[],
datas=[],
datas=[('appointment.json','.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
@@ -49,7 +49,6 @@ coll = COLLECT(
name='appointment',
)
import shutil
shutil.copyfile('./appointment.json', '{0}/appointment.json'.format(DISTPATH))
shutil.copyfile('./contact_all.xlsx', '{0}/contact_all.xlsx'.format(DISTPATH))
shutil.copyfile('./config.ini', '{0}/config.ini'.format(DISTPATH))
shutil.copytree('./venv/lib/python3.8/site-packages/grpc/_cython/_credentials', '{0}/appointment/grpc/_cython/_credentials'.format(DISTPATH))
BIN
View File
Binary file not shown.
+7 -1
View File
@@ -1,8 +1,14 @@
import configparser
import os
import getpass
from pathlib import Path
home = str(Path.home())
config = configparser.ConfigParser()
config.read('./config.ini')
print("home path: " + home)
# check the config file exsistence
config_file_path = home + "/config.ini"
config.read(config_file_path)
CONTACT_LIST_FILE = config['DEFAULT']['contact_list_file']
FIREBASE_CONFIG_FILE = config['DEFAULT']['firebase_config_file']
LOGS_DIR = config['DEFAULT']['LOGS_DIR']
+9 -7
View File
@@ -13,7 +13,7 @@ logger = logging.getLogger()
logger.addHandler(logging.StreamHandler(stream=sys.stdout))
def start_book(start_number, end_number, store_choose_state=0, max_workers=10):
def start_book(start_number, end_number, store_choose_state=0, max_workers=10, proxy_type=0):
# read the contact, and contact the 2 objects together
excel_reader = ExcelHelper()
all_contacts = excel_reader.read_contacts()
@@ -23,14 +23,16 @@ def start_book(start_number, end_number, store_choose_state=0, max_workers=10):
logger.info(contacts)
with ThreadPoolExecutor(max_workers=max_workers) as executor:
for contact in contacts:
proxy = get_proxy(contact.phone)
proxy = get_proxy(contact.phone, proxy_type)
# start the task in thread
executor.submit(CommandorPage(contact, store_type=store_choose_state).start_page, proxy)
executor.submit(CommandorPage(contact, store_type=store_choose_state, proxy_type=proxy_type).start_page,
proxy)
def get_proxy(phone_number):
random_id_number = str(phone_number)[1:len(str(phone_number))]
proxy_username = "panleicim-res-fr-" + random_id_number
def get_proxy(phone_number, proxy_type=0):
# random_id_number = str(phone_number)[1:len(str(phone_number))]
random_id_number = params.get_random_id_number_for_proxy()
proxy_username = params.get_proxy_name_prefix(proxy_type) + random_id_number
logger.info("proxy_username is " + proxy_username)
proxy = {
"server": params.PROXY_SERVER,
@@ -42,4 +44,4 @@ def get_proxy(phone_number):
if __name__ == '__main__':
# 修改联系人行,结束联系人行 第三个参数store等于0的时候是随机,传入1的时候是总店
start_book(16, 16, store_choose_state=0)
start_book(16, 16, store_choose_state=0, proxy_type=0)
+8
View File
@@ -10,6 +10,14 @@ oracle_log_sender = LogSender()
# proxy
PROXY_SERVER = "http://gw.ntnt.io:5959"
PROXY_PASSWORD = "94sY7zwBG13i"
PROXY_NAME_PREFIX_RES = "panleicim-res-fr-"
PROXY_NAME_PREFIX_CC = "panleicim-cc-fr-"
def get_proxy_name_prefix(proxy_type = 0) -> str:
if proxy_type ==0:
return PROXY_NAME_PREFIX_RES
else:
return PROXY_NAME_PREFIX_CC
def get_random_id_number_for_proxy() -> str:
+1
View File
@@ -10,6 +10,7 @@ import definitions
class PublishType(Enum):
SUCCESS = "SUCCESS"
ERROR = "ERROR"
PENDING = "PENDING"
@dataclass_json
+5 -1
View File
@@ -24,7 +24,11 @@ class ExcelHelper:
raw_name = contact_dict['name'].strip()
name = raw_name.split(' ')
last_name = name[0]
first_name = name[-1]
if len(name) == 2:
first_name = name[-1]
else:
first_name = ''.join(name[1:len(name)])
contact = ContactPojo(phone_number=contact_dict['phone'],
last_name=last_name,
first_name=first_name,
+41 -20
View File
@@ -1,5 +1,6 @@
import logging
import random
import re
import string
import threading
import time
@@ -18,6 +19,7 @@ RDV_URL = "https://rendezvousparis.hermes.com/client/register"
# RDV_URL = "file:///Users/lpan/Downloads/test_appointment.html"
# RDV_URL = "https://api.ipify.org"
# RDV_URL ="https://bot.sannysoft.com/"
REGEX_RDV_URL = "https:\/\/rendezvousparis\.hermes\.com\/client\/register\/[A-Z0-9]+"
otp_value = None
OTP_FIELD_ID = "#sms_code"
MESSAGE_FIELD_CLASS = ".message"
@@ -28,10 +30,11 @@ TOO_MANY_REQUEST_ERROR_MESSAGE = "Due to a large number of requests"
CAPTCHA_ERROR_MESSAGE = "Error verifying captcha, please try again"
TIME_OUT = 400000
OTP_TIMEOUT = 240
PAGE_TIMEOUT = 30000
def get_random_wait_time() -> float:
wait_time = random.randint(0, 10) / 10.0 * 5
wait_time = random.randint(0, 10) / 10.0 * 1
return wait_time
@@ -43,11 +46,12 @@ class Tls(threading.local):
class CommandorPage:
tls = Tls()
def __init__(self, contact: ContactPojo, store_type=0):
def __init__(self, contact: ContactPojo, store_type=0, proxy_type=0):
self.otp_value = None
self.logger = logging.getLogger("CommandorPage")
self.is_finished = False
self.contact = contact
self.proxy_type = proxy_type
# 0: random
# 1: faubourg
# 2: George
@@ -72,7 +76,7 @@ class CommandorPage:
self.termine()
def _run(self, e: threading.Event, proxy):
print("will start browser")
self.logger.info("will start browser")
self.on_success_listener = on_success
# reset otp_value to None
self.otp_value = None
@@ -80,21 +84,14 @@ class CommandorPage:
first_page = None
while first_page is None:
first_page = self.start_browser(proxy, self.tls.playwright, devices)
proxy_username = "panleicim-res-fr-" + params.get_random_id_number_for_proxy()
proxy_username = params.get_proxy_name_prefix(self.proxy_type) + params.get_random_id_number_for_proxy()
self.logger.info("proxy_username is " + proxy_username)
proxy = {
"server": params.PROXY_SERVER,
"username": proxy_username,
"password": params.PROXY_PASSWORD
}
self._setName(self.contact.last_name, self.contact.first_name)
self._setPhoneCountryAndStore()
self._setPhoneNumber(self.contact.phone)
self._set_email(self.contact.mail)
self.setIdNumber(self.contact.passport)
#
self._checkCgu()
self.click_recapcha_checkbox()
self.fill_fields()
# wait for sms_code field
# self.clickOnValidBtn()
self.thread_event = e
@@ -119,9 +116,18 @@ class CommandorPage:
self.logger.info("timeout")
self.termine()
def fill_fields(self):
self._set_name(self.contact.last_name, self.contact.first_name)
self._setPhoneCountryAndStore()
self._setPhoneNumber(self.contact.phone)
self._set_email(self.contact.mail)
self.setIdNumber(self.contact.passport)
#
self._checkCgu()
def start_browser(self, proxy, pwright, device) -> Union[str, None]:
try:
self.browser = pwright.webkit.launch(headless=False, timeout=90000, proxy=proxy)
self.browser = pwright.webkit.launch(headless=False, timeout=PAGE_TIMEOUT, proxy=proxy)
self.logger.info("模拟设备: " + device)
pixel_2 = pwright.devices[device]
context = self.browser.new_context(**pixel_2, locale='en-GB')
@@ -136,7 +142,8 @@ class CommandorPage:
}
""")
self.page.on("load", self._on_page_loaded)
self.page.goto(RDV_URL, timeout=90000)
self.page.on("response", self.handle_response)
self.page.goto(RDV_URL, timeout=PAGE_TIMEOUT)
return self.page.content()
except Exception as error:
params.oracle_log_sender.send_error(str(error))
@@ -145,6 +152,12 @@ class CommandorPage:
self.browser.close()
return None
def handle_response(self, response):
pattern = re.compile(REGEX_RDV_URL)
if pattern.match(response.url):
self.logger.info("result url found: " + response.url)
self.publish_message_to_queue(self.contact, PublishType.PENDING, response.url)
def start_page(self, proxy):
e = threading.Event()
self._run(e, proxy)
@@ -153,6 +166,8 @@ class CommandorPage:
self.logger.info("page loaded")
# self.logger.info("content is " + self.page.content())
self.logger.info("url is " + self.page.url)
if self.page.url == RDV_URL:
self.fill_fields()
message = self.page.content()
if CONFIRMED_MESSAGE in message:
# publish the successful message
@@ -185,14 +200,18 @@ class CommandorPage:
except Exception as error:
self.logger.error(error)
def _setName(self, lastName, firstName):
def _set_name(self, lastName, firstName):
time.sleep(get_random_wait_time())
try:
self.page.evaluate("""(name)=> {
document.getElementById("surname").focus();
document.getElementById("surname").value = name.lastName;
let surname = document.getElementById("surname");
if(surname.value.length == 0){
surname.focus();
surname.value = name.lastName;
document.getElementById("name").focus();
document.getElementById("name").value = name.firstName}""", {'lastName': lastName, 'firstName': firstName})
document.getElementById("name").value = name.firstName
}}
""", {'lastName': lastName, 'firstName': firstName})
except Exception as error:
self.logger.error(error)
@@ -229,8 +248,10 @@ class CommandorPage:
time.sleep(get_random_wait_time())
try:
self.page.evaluate("""(email)=>{
document.getElementById("email").focus();
document.getElementById("email").value = email;}""", email)
let emailElement = document.getElementById("email")
if(emailElement.value.length == 0){
emailElement.focus();
document.getElementById("email").value = email;}}""", email)
except Exception as error:
self.logger.error(error)