const ExcelUtil = require("./excel/ExcelUtil"); const CommandorPage = require("./workers/CommandorPage"); const {MongoManager, formatDate} = require("./workers/mongo_manager"); const alert = require('alert'); const schedule = require("node-schedule"); const DeviceExcludeMode = require("./models/DeviceExcludeMode"); const {Sender} = require("./queue/Sender"); const {devices} = require("./android/adb"); const mongoManager = new MongoManager(); const SEVEN_DAYS_IN_S = 3600 * 24 * 7; // const NINETY_DAYS_IN_S = 3600 * 24 * 30 * 3; const NINETY_DAYS_IN_S = 30 * 3; let excelUtil = new ExcelUtil(); let collectionName = formatDate(new Date()) let excludeMode = DeviceExcludeMode.ZERO let three_to_excludes = [] let four_to_excludes = ["bec11752", "4e8ca027", "hi7ljr5xduyt9pfi", "EPHUT20825001518"] let seven_to_excludes = ["4e8ca027", "hi7ljr5xduyt9pfi", "EPHUT20825001518", "bec11752", "fuljaueqguugf6pn", "EPHUT20825001518"] let six_to_excludes = ["4e8ca027", "hi7ljr5xduyt9pfi", "EPHUT20825001518", "bec11752", "07fbd156", "NFD669QK8XNFSCNN", "6X494TTWQGFALB79", "71a0371d", "YP6HVKLFE67T598L"] let nine_to_excludes = ["bec11752", "4e8ca027", "hi7ljr5xduyt9pfi", "47e7e36b", "p7d6nbw8cu7duous", "njzxojhim7gedyvw", "fmiz5pa6rsx4u4ts", "fuljaueqguugf6pn", "EPHUT20825001518"] let for_scrpay = ["07fbd156", "47e7e36b", "4f55c3d4", "5ac879a2", "69db59f0", "71a0371d", "774687ff", "7b71fb20", "8f76f9e7", "99cyfiaebqcy6poj", "EPHUT20825001518", "J4AXB761H2322WJ", "W8GMFELRHIKZS84T", "ai9xv8hy599hvkee", "b41c1b72", "bec11752", "becb6e99", "c3ba032e", "d54e946", "fmiz5pa6rsx4u4ts", "fuljaueqguugf6pn", "fy65eqs4wkvcpf9h", "hi7ljr5xduyt9pfi", "njzxojhim7gedyvw", "p7d6nbw8cu7duous"] attributedPorts = [] const device_port_info = new Map(); startPort = 9000 async function filterAlreadyBookedContacts(contactList) { console.log("getAllSuccessfulItemsForDay()") let alreadyBookedContacts = await mongoManager.getAllSuccessfulItemsForDay(collectionName); let contactsToBook = []; contactList.forEach((contact) => { if (alreadyBookedContacts.find((bookedContact) => bookedContact.email === contact.mail) === undefined) { contactsToBook.push(contact) } }) return contactsToBook; } async function needToBook(contact, mongoManager, alreadyBooked) { console.log("check contact with email " + contact.mail) let blackListItems = []; let needToBook = true; await alreadyBooked.forEach((bookedItem) => { if (bookedItem.email === contact.mail) { needToBook = false; } } ) if (needToBook) { await blackListItems.forEach((blackListItem) => { if (blackListItem.mail === contact.mail) { console.log("=====handle blacklist item===="); console.log("update_at_s is " + blackListItem.update_at_in_s) console.log("black list email is " + blackListItem.mail) needToBook = blackListItem.update_at_in_s + SEVEN_DAYS_IN_S <= (new Date()) / 1000; if (!needToBook) { console.log("contact in blacklist -->skip"); } } }) } return needToBook } async function startBook(contactPojo, device, sender, selectedStore, audioAnalyse, alertBeep, port) { console.log(`model: ${device.model}`); console.log(`serial: ${device.serial}`); let alreadyBooked = await mongoManager.getAllSuccessfulItemsForDay(collectionName); const d = new Date(); let hour = d.getHours(); if (hour >= 19) { console.log("do not continue after 19h") return } if (await needToBook(contactPojo, mongoManager, alreadyBooked)) { let commandor = new CommandorPage(contactPojo, device, sender, mongoManager, selectedStore, audioAnalyse, alertBeep, port); //read contacts form excel return await commandor.loadPage(); } else { console.log("do not send request --> skip") } } async function startWithList(contacts, device, sender, selectedStore, audioAnalyse, alertBeep, port) { let duplicatedList = [].concat(contacts).concat(contacts).concat(contacts) await duplicatedList.reduce(async (promise, contactPojo) => { // This line will wait for the last async function to finish. // The first iteration uses an already resolved Promise // so, it will immediately continue. await promise; const contents = await startBook(contactPojo, device, sender, selectedStore, audioAnalyse, alertBeep, port); console.log(contents); }, Promise.resolve()); } async function scheduleBookWithNumbers(startNumber, endNumber, selectedStore, pathToExcelFile = '/Users/lpan/Desktop/contact_all.xlsx', audioAnalyse = true, alertBeep = false) { console.log("scheduleBookWithNumbers() called") alert("定时成功") schedule.scheduleJob('30 10 * * *', function () { console.log("start startBookWithNumbers") startBookWithNumbers(startNumber, endNumber, selectedStore, pathToExcelFile, audioAnalyse, alertBeep) }) } function shuffle(array) { let currentIndex = array.length, randomIndex; // While there remain elements to shuffle. while (currentIndex !== 0) { // Pick a remaining element. randomIndex = Math.floor(Math.random() * currentIndex); currentIndex--; // And swap it with the current element. [array[currentIndex], array[randomIndex]] = [ array[randomIndex], array[currentIndex]]; } return array; } function getContactListForDevice(device, allContactList) { let contactList = []; allContactList.forEach((contact) => { if (contact.serial === device.serial) { contactList.push(contact) } }) return contactList; } async function startBookWithNumbers(startNumber, endNumber, selectedStore, pathToExcelFile = '/Users/lpan/Desktop/contact_all.xlsx', audioAnalyse = true, alertBeep = false) { console.log("startBookWithNumbers() called, with alertBeep:" + alertBeep) console.log("startBookWithNumbers() called, with audioAnalyse:" + audioAnalyse) let allContactList = excelUtil.readContacts(pathToExcelFile); let contactList; if (endNumber <= allContactList.length) { contactList = allContactList.slice(startNumber, endNumber); } else { contactList = allContactList.slice(startNumber, allContactList.length); } if (contactList.length === 0) { alert("联系人数为0") return } function startForwordingForDevice(device) { console.log("startForwordingForDevice() called") const execSync = require('child_process').execSync; // get attributed port let attributedPort = device_port_info[device.serial] if (attributedPort) { let cmd = 'adb -s ' + device.serial + " forward tcp:" + attributedPort + " localabstract:chrome_devtools_remote"; console.log("cmd is " + cmd); const output = execSync(cmd, {encoding: 'utf-8'}); // the default is 'buffer' console.log('Output was:\n', output); } else { attributedPort = startPort; startPort++; let cmd = 'adb -s ' + device.serial + " forward tcp:" + attributedPort + " localabstract:chrome_devtools_remote"; console.log("cmd is " + cmd); const output = execSync(cmd, {encoding: 'utf-8'}); // the default is 'buffer' console.log('Output was:\n', output); } // start chrome // device.shell("am start -n com.brave.browser/com.google.android.apps.chrome.Main") return attributedPort } let sender = new Sender() sender.initConnection().then((r) => { console.log("queue connected") console.log("connect to mongodb") mongoManager.connect().then(r => { console.log("successfully connected to mongodb") filterAlreadyBookedContacts(contactList).then((listWithoutBlackContact) => { console.log("will call filterAlreadyAcceptedContacts") console.log("number of contacts to book:" + listWithoutBlackContact.length) devices().then((devices) => { if (devices.length === 0) { alert("未找到连接的设备"); return } let device_to_excludes = three_to_excludes; if (excludeMode === DeviceExcludeMode.FOUR) { device_to_excludes = four_to_excludes; } else if (excludeMode === DeviceExcludeMode.THREE) { device_to_excludes = three_to_excludes; } else if (excludeMode === DeviceExcludeMode.NINE) { device_to_excludes = nine_to_excludes; } else if (excludeMode === DeviceExcludeMode.SEVEN) { device_to_excludes = seven_to_excludes } else if (excludeMode === DeviceExcludeMode.SIX) { device_to_excludes = six_to_excludes } else if (excludeMode === DeviceExcludeMode.ZERO) { device_to_excludes = [] } filteredDeviceList = devices.filter(device => !device_to_excludes.includes(device.serial)) let segmentNumber = listWithoutBlackContact.length / filteredDeviceList.length; console.log("connected device number:" + filteredDeviceList.length) console.log("segmentNumber:" + segmentNumber) for (let i = 0; i < filteredDeviceList.length; i++) { let device = filteredDeviceList[i]; let port = startForwordingForDevice(device) // let _contactList = listWithoutBlackContact.slice(i * segmentNumber, segmentNumber * (i + 1)) let _contactList = getContactListForDevice(device, listWithoutBlackContact) console.log("contactList: for device:" + device.serial + " has " + _contactList.length) startWithList(_contactList, device, sender, selectedStore, audioAnalyse, alertBeep, port); } }) }) }); }) } module.exports = {startBookWithNumbers, scheduleBookWithNumbers}