log to file
This commit is contained in:
+4
-1
@@ -28,7 +28,10 @@
|
||||
<option value="sevres">Hermès Sèvres</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="device_list"/>
|
||||
<div>
|
||||
<label for="device_list">连接的手机</label>
|
||||
<div id="device_list"/>
|
||||
</div>
|
||||
<br/>
|
||||
<button id="start_book_btn">开始约会
|
||||
</button>
|
||||
|
||||
@@ -19,7 +19,7 @@ const createWindow = () => {
|
||||
startBook(startNumber, endNumber, selectedStore)
|
||||
})
|
||||
ipcMain.handle('scan-devices', scanDevices)
|
||||
win.webContents.openDevTools();
|
||||
// win.webContents.openDevTools();
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
+2
-1
@@ -17,7 +17,8 @@
|
||||
"mongodb": "^4.9.1",
|
||||
"mongoose": "^6.5.4",
|
||||
"node-xlsx": "^0.21.0",
|
||||
"playwright": "1.23.0"
|
||||
"playwright": "1.23.0",
|
||||
"winston": "^3.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.0.0-beta.66",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
let startNumber = 0;
|
||||
let endNumber = 0;
|
||||
let selectedStore = 'faubourg';
|
||||
let selectedStore = 'random';
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
window.appointment.scanDevices().then((deviceList) => {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
const {createLogger, format, transports} = require('winston');
|
||||
const {_, formatDate} = require('../workers/mongo_manager')
|
||||
const {printf, label, timestamp, combine} = format;
|
||||
|
||||
const myFormat = printf(({level, message, label, timestamp}) => {
|
||||
return `${timestamp} [${label}] ${level}: ${message}`;
|
||||
});
|
||||
|
||||
const appointmentLogger = createLogger({
|
||||
level: 'info',
|
||||
format: combine(
|
||||
label({label: 'appointment'}),
|
||||
timestamp(),
|
||||
myFormat
|
||||
),
|
||||
transports: [
|
||||
new transports.File({filename: "appointment_" + formatDate(new Date()) + ".log"}),
|
||||
],
|
||||
});
|
||||
|
||||
module.exports = appointmentLogger
|
||||
@@ -1,10 +1,10 @@
|
||||
const {_android: android, devices} = require("playwright");
|
||||
const {SolveCaptcha, TWO_CAPTCHA_CONNECTION_FAILED} = require("./SolveCaptcha");
|
||||
const ReserveResultPojo = require("../models/ReserveResultPojo");
|
||||
const appointmentLogger = require("../utiles/LoggerUtils")
|
||||
const PublishType = require("../models/PublishType");
|
||||
const beep = require('beepbeep')
|
||||
// const RDV_URL = "http://192.168.1.16:8000/test_appointment.html"
|
||||
const RDV_URL = "https://rendezvousparis.hermes.com/client/register";
|
||||
const RDV_URL = "http://192.168.0.44:8000/test_appointment.html"
|
||||
// const RDV_URL = "https://rendezvousparis.hermes.com/client/register";
|
||||
BLANK_URL = "about:blank"
|
||||
const ERROR_CAPTCHA_UNSOLVABLE = "ERROR_CAPTCHA_UNSOLVABLE";
|
||||
|
||||
@@ -49,6 +49,10 @@ function getRandomWaitTime() {
|
||||
return getRandom() * 1000
|
||||
}
|
||||
|
||||
function log(message) {
|
||||
appointmentLogger.log({level: "info", message: message})
|
||||
}
|
||||
|
||||
class CommandorPage {
|
||||
constructor(contact, device, mongoManager, selectedStore = DEFAULT_STORE) {
|
||||
this.contact = contact;
|
||||
@@ -59,9 +63,10 @@ class CommandorPage {
|
||||
this.isTerminated = false;
|
||||
}
|
||||
|
||||
|
||||
async loadPage() {
|
||||
// Connect to the device.
|
||||
console.log("loadPage() called");
|
||||
log("loadPage() called");
|
||||
await this.device.shell('am force-stop com.android.chrome');
|
||||
const context = await this.device.launchBrowser();
|
||||
// await context.clearCookies()
|
||||
@@ -78,14 +83,14 @@ class CommandorPage {
|
||||
try {
|
||||
await this.page.goto(RDV_URL, {timeout: 90 * 1000});
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
log(e)
|
||||
this.isTerminated = true
|
||||
}
|
||||
|
||||
let cancel
|
||||
const intervalTask = setInterval(() => {
|
||||
if (this.isTerminated) {
|
||||
console.log("request terminated, will close device")
|
||||
log("request terminated, will close device")
|
||||
context.close()
|
||||
// this.page.close()
|
||||
this.device.close()
|
||||
@@ -100,7 +105,7 @@ class CommandorPage {
|
||||
fulfill(Promise.resolve())
|
||||
}
|
||||
setTimeout(fulfill, TIME_OUT, 5)
|
||||
}).then(console.log)
|
||||
}).then(log)
|
||||
}
|
||||
|
||||
async chooseCountry(page) {
|
||||
@@ -115,7 +120,7 @@ class CommandorPage {
|
||||
await page.selectOption(COUNTRY_ID, 'FR');
|
||||
await delay(getRandomWaitTime())
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log(e);
|
||||
this.isTerminated = true;
|
||||
}
|
||||
// await page.click(COUNTRY_ID);
|
||||
@@ -130,7 +135,7 @@ class CommandorPage {
|
||||
await page.locator(EMAIL_ID).fill(this.contact.mail);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
log(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +146,7 @@ class CommandorPage {
|
||||
await page.locator(PHONE_NUMBER).fill("0" + this.contact.phoneNumber)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log(e);
|
||||
this.isTerminated = true;
|
||||
}
|
||||
|
||||
@@ -158,7 +163,7 @@ class CommandorPage {
|
||||
await page.locator(FIRST_NAME).fill(this.contact.firstName)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log(e);
|
||||
this.isTerminated = true
|
||||
}
|
||||
}
|
||||
@@ -172,7 +177,7 @@ class CommandorPage {
|
||||
await page.locator(PASSPORT_ID).fill(this.contact.passportNumber.toString())
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log(e);
|
||||
this.isTerminated = true;
|
||||
}
|
||||
|
||||
@@ -188,7 +193,7 @@ class CommandorPage {
|
||||
await page.locator(PROCESSING_ID).click()
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log(e);
|
||||
this.isTerminated = true;
|
||||
}
|
||||
}
|
||||
@@ -196,7 +201,7 @@ class CommandorPage {
|
||||
async chooseStore(page) {
|
||||
try {
|
||||
if (!page.isClosed()) {
|
||||
if (selectedStore !== "random") {
|
||||
if (this.selectedStore !== "random") {
|
||||
await page.locator(PREFER_STORE).focus()
|
||||
await delay(1000)
|
||||
await page.click(PREFER_STORE);
|
||||
@@ -204,7 +209,7 @@ class CommandorPage {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log(e);
|
||||
this.isTerminated = true;
|
||||
}
|
||||
// await page.click(PREFER_STORE);
|
||||
@@ -212,7 +217,7 @@ class CommandorPage {
|
||||
|
||||
|
||||
async fillFields(page) {
|
||||
console.log("fillFields called")
|
||||
log("fillFields called")
|
||||
if (!this.isFillingFields) {
|
||||
this.isFillingFields = true;
|
||||
await this.chooseStore(page);
|
||||
@@ -243,7 +248,7 @@ class CommandorPage {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
log(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +259,7 @@ class CommandorPage {
|
||||
}
|
||||
this.captchaSolver = new SolveCaptcha(page);
|
||||
await this.captchaSolver.start((solution) => {
|
||||
console.log("solution is: " + solution);
|
||||
log("solution is: " + solution);
|
||||
if (solution !== ERROR_CAPTCHA_UNSOLVABLE && solution !== TWO_CAPTCHA_CONNECTION_FAILED) {
|
||||
try {
|
||||
if (!page.isClosed()) {
|
||||
@@ -266,7 +271,7 @@ class CommandorPage {
|
||||
this.clickValid();
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
log(e)
|
||||
this.isTerminated = true;
|
||||
}
|
||||
} else {
|
||||
@@ -282,7 +287,7 @@ class CommandorPage {
|
||||
if (content.toString().includes(captcha_url)) {
|
||||
await this.checkAudioBtn();
|
||||
beep(20)
|
||||
console.log("发现datadome");
|
||||
log("发现datadome");
|
||||
} else {
|
||||
if (currentPage.url() === RDV_URL) {
|
||||
await this.fillFields(this.page);
|
||||
@@ -290,7 +295,7 @@ class CommandorPage {
|
||||
await this.getErrors()
|
||||
} else {
|
||||
if (content.includes(MESSAGE_URL_VALIDATION_FR) || content.includes(MESSAGE_URL_VALIDATION_EN)) {
|
||||
console.log("successful");
|
||||
log("successful");
|
||||
await this.push_message_to_queue(PublishType.SUCCESS);
|
||||
} else {
|
||||
// try to get errors
|
||||
@@ -304,17 +309,17 @@ class CommandorPage {
|
||||
// let iframe = await this.page.locator("iframe").contentFrame;
|
||||
// let audioBtn = iframe.locator("#captcha__audio__button");
|
||||
// if (audioBtn) {
|
||||
// console.log("audioBtn found")
|
||||
// log("audioBtn found")
|
||||
// } else {
|
||||
// console.log("audioBtn not found")
|
||||
// log("audioBtn not found")
|
||||
// }
|
||||
}
|
||||
|
||||
async onResponse(response) {
|
||||
// let rex = new RegExp(REGEX_RDV_URL)
|
||||
// console.log("onResponse with url:" + response.url())
|
||||
// log("onResponse with url:" + response.url())
|
||||
// if (rex.test(response.url())) {
|
||||
// console.log("rdv url found:" + response.url())
|
||||
// log("rdv url found:" + response.url())
|
||||
// await this.push_message_to_db(PublishType.SUCCESS, response.url())
|
||||
// }
|
||||
}
|
||||
@@ -356,11 +361,11 @@ class CommandorPage {
|
||||
let errorItem = this.page.locator("div.alert");
|
||||
if (errorItem) {
|
||||
let errorContent = await errorItem.innerHTML();
|
||||
console.log("error:" + errorContent);
|
||||
log("error:" + errorContent);
|
||||
this.handleError(errorContent);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user