From 94e7f54476d9249918de099c2911763fd2915a17 Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 10 Nov 2023 02:50:00 -0800 Subject: [PATCH] Initial POC --- app.js | 211 +++++++++++++++++++++++++++++++++++++++++++++++++ bookmarklet.js | 1 + index.htm | 12 +++ 3 files changed, 224 insertions(+) create mode 100644 app.js create mode 100644 bookmarklet.js create mode 100644 index.htm diff --git a/app.js b/app.js new file mode 100644 index 0000000..c6a007c --- /dev/null +++ b/app.js @@ -0,0 +1,211 @@ +/* TODO: + * Inject div + * start/stop buttons + * How often should the status check be performed? [] seconds (have interval use that value) + * show rowAction1[] //AlwaysWin + * show rowAction2[] //AlwaysTie + * show rowAction3[] //WatchTie + * PriceChangeOverTime Chart + * For each countyRow inject + * "rowAction" dropdown with options: [Ignore,1 - Ensure I am highest bidder, 2 - Make sure I am Tied, 3 - Only watch tied bid] + * save to analytics checkbox + * bidcap input + * Sell leads that don't fit your criteria but you can't return on the secondary market. +*/ + +//Win+Save +//https://leads.needtosellmyhousefast.com/app/subscription/84035 +var currentLocation = window.location.href; +const destUrl = "https://leads.needtosellmyhousefast.com/app/subscriptions/"; +if(currentLocation != destUrl) { + window.location.href = destUrl; +} + +//location.reload() +const Status_Top = "Top Bid"; +const Status_Tied = "Tied Bid"; +const Status_Low = "Low Bid"; + +function getCountyInfoNew(countyId){ + const counties = document.querySelectorAll('.subscription-status'); + for (let county of counties) { + if(county.dataset.subscription_id == countyId) { + let bidController = getControllerForCounty(county); + return bidController; + } + } +} + +function getCountyInfo(countyId){ + const counties = document.querySelectorAll('.subscription-status'); + for (let county of counties) { + if(county.dataset.subscription_id == countyId) { + let countyRow = county.closest("tr"); + let bidController = {}; + bidController.countyRow = countyRow; + + bidController.isEnabled = county.checked; + bidController.id = county.dataset.subscription_id; + bidController.name = county.closest("div").getElementsByTagName('a')[0].innerText; + bidController.bid = countyRow.querySelector('.bid-controller--bid').value; + bidController.status = countyRow.querySelector(".bid-status").innerText.trim(); //countyRow.querySelector(".bid-status").dataset.bid_status; + bidController.isWinning = (bidController.status == Status_Top); + bidController.winningBid = "unknown"; + bidController.tieBid = "unknown"; + bidController.floorBid = "unknown"; + bidController.btnSave = countyRow.querySelector('.bid-controller-btn--save'); + bidController.btnBidUp = countyRow.querySelector('.bid-controller-btn--increment'); + bidController.btnBidDown = countyRow.querySelector('.bid-controller-btn--decrement'); + return bidController; + } + } +} + +function findTieBid(bidController) { + let latestBidInfo = getCountyInfo(bidController.id); + + //Perhaps we currently have a bid that is too high. + while(latestBidInfo.isWinning) { + bidController.winningBid = latestBidInfo.bid; + bidController.btnBidDown.click(); + latestBidInfo = findTieBid(bidController); + } + + //Are we currently tied? + if(latestBidInfo.status === Status_Tied) { + bidController.tieBid = latestBidInfo.bid; + return latestBidInfo; + } + + //Deal with situations were we are too low. + while(!latestBidInfo.isWinning) { + if(latestBidInfo.status === Status_Tied) { + bidController.tieBid = latestBidInfo.bid; + return latestBidInfo; + } + + bidController.floorBid = latestBidInfo.bid; + bidController.btnBidUp.click(); + latestBidInfo = findTieBid(bidController); + } + //We should not make it to here but if we do return the latest info we have. + return latestBidInfo; +} + +function findMaxBid(bidController) { + let latestBidInfo = getCountyInfo(bidController.id); + if(latestBidInfo.isWinning) { + bidController.winningBid = latestBidInfo.bid; + } else { + bidController.btnBidUp.click(); + latestBidInfo = getCountyInfo(bidController.id); + while(!latestBidInfo.isWinning) { + latestBidInfo = findMaxBid(bidController); + } + bidController.winningBid = latestBidInfo.winningBid; + } + return latestBidInfo; +} + +function getControllerForCounty(county) { + let countyRow = county.closest("tr"); + let bidController = {}; + bidController.countyRow = countyRow; + + bidController.isEnabled = county.checked; + bidController.id = county.dataset.subscription_id; + bidController.name = county.closest("div").getElementsByTagName('a')[0].innerText; + bidController.bid = countyRow.querySelector('.bid-controller--bid').value; + bidController.status = countyRow.querySelector(".bid-status").innerText.trim(); //countyRow.querySelector(".bid-status").dataset.bid_status; + bidController.isWinning = (bidController.status == Status_Top); + bidController.winningBid = "unknown"; + bidController.tieBid = "unknown"; + bidController.floorBid = "unknown"; + bidController.btnSave = countyRow.querySelector('.bid-controller-btn--save'); + bidController.btnBidUp = countyRow.querySelector('.bid-controller-btn--increment'); + bidController.btnBidDown = countyRow.querySelector('.bid-controller-btn--decrement'); + return bidController; +} + +function winCounty(countyInfo, saveChanges){ + let tieData = findTieBid(countyInfo); + countyInfo.btnBidUp.click(); + if(saveChanges) { + countyInfo.btnSave.click(); + } +} + +function winAll(includeActive, includeInactive, saveChanges){ + const counties = document.querySelectorAll('.subscription-status'); + for (let county of counties) { + let okToChange = false; + if(includeActive && county.checked) { + okToChange = true; + } + if(includeInactive && !county.checked) { + okToChange = true; + } + + if(okToChange) { + let controller = getControllerForCounty(county); + let tieData = findTieBid(controller); + controller.btnBidUp.click(); + if(saveChanges) { + controller.btnSave.click(); + } + } + } +} + +function tieCounty(countyInfo, saveChanges){ + let tieData = findTieBid(countyInfo); + if(saveChanges) { + countyInfo.btnSave.click(); + } +} + +function tieAll(includeActive, includeInactive, saveChanges){ + const counties = document.querySelectorAll('.subscription-status'); + for (let county of counties) { + let okToChange = false; + if(includeActive && county.checked) { + okToChange = true; + } + if(includeInactive && !county.checked) { + okToChange = true; + } + + if(okToChange) { + let controller = getControllerForCounty(county); + let tieData = findTieBid(controller); + if(saveChanges) { + controller.btnSave.click(); + } + } + } +} + +const keepWinning = () => { + winCounty(washington, true); + winCounty(marion,true); + tieCounty(clackamas,false); + tieCounty(cascade,false); + console.log('Still winning at '+ new Date()); + //TODO store tie values for statistical analysis over time. +}; + +let cascade = getCountyInfo("84034"); +let marion = getCountyInfo("87833"); +let washington = getCountyInfo("84035"); +let clackamas = getCountyInfo("84037"); +//var tieData = findTieBid(clackamas); + +keepWinning(); +const interval = setInterval(keepWinning, 300000); // Repeat every 300 seconds /5 minutes +//clearInterval(interval); // The interval will no longer run +//win(true,true,false); +//tie(true,true,false); + + +///BOOKMARKLET +//https://www.yourjs.com/bookmarklet/ diff --git a/bookmarklet.js b/bookmarklet.js new file mode 100644 index 0000000..bbba2e8 --- /dev/null +++ b/bookmarklet.js @@ -0,0 +1 @@ +javascript:var%20%24jscomp%3D%24jscomp%7C%7C%7B%7D%3B%24jscomp.scope%3D%7B%7D%3B%24jscomp.arrayIteratorImpl%3Dfunction(b)%7Bvar%20a%3D0%3Breturn%20function()%7Breturn%20a%3Cb.length%3F%7Bdone%3A!1%2Cvalue%3Ab%5Ba%2B%2B%5D%7D%3A%7Bdone%3A!0%7D%7D%7D%3B%24jscomp.arrayIterator%3Dfunction(b)%7Breturn%7Bnext%3A%24jscomp.arrayIteratorImpl(b)%7D%7D%3B%24jscomp.makeIterator%3Dfunction(b)%7Bvar%20a%3D%22undefined%22!%3Dtypeof%20Symbol%26%26Symbol.iterator%26%26b%5BSymbol.iterator%5D%3Bif(a)return%20a.call(b)%3Bif(%22number%22%3D%3Dtypeof%20b.length)return%20%24jscomp.arrayIterator(b)%3Bthrow%20Error(String(b)%2B%22%20is%20not%20an%20iterable%20or%20ArrayLike%22)%3B%7D%3Bvar%20currentLocation%3Dwindow.location.href%2CdestUrl%3D%22https%3A%2F%2Fleads.needtosellmyhousefast.com%2Fapp%2Fsubscriptions%2F%22%3BcurrentLocation!%3DdestUrl%26%26(window.location.href%3DdestUrl)%3Bvar%20Status_Top%3D%22Top%20Bid%22%2CStatus_Tied%3D%22Tied%20Bid%22%2CStatus_Low%3D%22Low%20Bid%22%3Bfunction%20getCountyInfoNew(b)%7Bvar%20a%3Ddocument.querySelectorAll(%22.subscription-status%22)%3Ba%3D%24jscomp.makeIterator(a)%3Bfor(var%20c%3Da.next()%3B!c.done%3Bc%3Da.next())if(c%3Dc.value%2Cc.dataset.subscription_id%3D%3Db)return%20getControllerForCounty(c)%7Dfunction%20getCountyInfo(b)%7Bvar%20a%3Ddocument.querySelectorAll(%22.subscription-status%22)%2Cc%3D%24jscomp.makeIterator(a)%3Bfor(a%3Dc.next()%3B!a.done%3Ba%3Dc.next())if(a%3Da.value%2Ca.dataset.subscription_id%3D%3Db)return%20b%3Da.closest(%22tr%22)%2Cc%3D%7B%7D%2Cc.countyRow%3Db%2Cc.isEnabled%3Da.checked%2Cc.id%3Da.dataset.subscription_id%2Cc.name%3Da.closest(%22div%22).getElementsByTagName(%22a%22)%5B0%5D.innerText%2Cc.bid%3Db.querySelector(%22.bid-controller--bid%22).value%2Cc.status%3Db.querySelector(%22.bid-status%22).innerText.trim()%2Cc.isWinning%3Dc.status%3D%3DStatus_Top%2Cc.winningBid%3D%22unknown%22%2Cc.tieBid%3D%22unknown%22%2Cc.floorBid%3D%22unknown%22%2Cc.btnSave%3Db.querySelector(%22.bid-controller-btn--save%22)%2Cc.btnBidUp%3Db.querySelector(%22.bid-controller-btn--increment%22)%2Cc.btnBidDown%3Db.querySelector(%22.bid-controller-btn--decrement%22)%2Cc%7Dfunction%20findTieBid(b)%7Bfor(var%20a%3DgetCountyInfo(b.id)%3Ba.isWinning%3B)b.winningBid%3Da.bid%2Cb.btnBidDown.click()%2Ca%3DfindTieBid(b)%3Bif(a.status%3D%3D%3DStatus_Tied)return%20b.tieBid%3Da.bid%2Ca%3Bfor(%3B!a.isWinning%3B)%7Bif(a.status%3D%3D%3DStatus_Tied)%7Bb.tieBid%3Da.bid%3Bbreak%7Db.floorBid%3Da.bid%3Bb.btnBidUp.click()%3Ba%3DfindTieBid(b)%7Dreturn%20a%7Dfunction%20findMaxBid(b)%7Bvar%20a%3DgetCountyInfo(b.id)%3Bif(a.isWinning)b.winningBid%3Da.bid%3Belse%7Bb.btnBidUp.click()%3Bfor(a%3DgetCountyInfo(b.id)%3B!a.isWinning%3B)a%3DfindMaxBid(b)%3Bb.winningBid%3Da.winningBid%7Dreturn%20a%7Dfunction%20getControllerForCounty(b)%7Bvar%20a%3Db.closest(%22tr%22)%2Cc%3D%7B%7D%3Bc.countyRow%3Da%3Bc.isEnabled%3Db.checked%3Bc.id%3Db.dataset.subscription_id%3Bc.name%3Db.closest(%22div%22).getElementsByTagName(%22a%22)%5B0%5D.innerText%3Bc.bid%3Da.querySelector(%22.bid-controller--bid%22).value%3Bc.status%3Da.querySelector(%22.bid-status%22).innerText.trim()%3Bc.isWinning%3Dc.status%3D%3DStatus_Top%3Bc.winningBid%3D%22unknown%22%3Bc.tieBid%3D%22unknown%22%3Bc.floorBid%3D%22unknown%22%3Bc.btnSave%3Da.querySelector(%22.bid-controller-btn--save%22)%3Bc.btnBidUp%3Da.querySelector(%22.bid-controller-btn--increment%22)%3Bc.btnBidDown%3Da.querySelector(%22.bid-controller-btn--decrement%22)%3Breturn%20c%7Dfunction%20winCounty(b%2Ca)%7BfindTieBid(b)%3Bb.btnBidUp.click()%3Ba%26%26b.btnSave.click()%7Dfunction%20winAll(b%2Ca%2Cc)%7Bvar%20e%3Ddocument.querySelectorAll(%22.subscription-status%22)%3Be%3D%24jscomp.makeIterator(e)%3Bfor(var%20d%3De.next()%3B!d.done%3Bd%3De.next())%7Bd%3Dd.value%3Bvar%20f%3D!1%3Bb%26%26d.checked%26%26(f%3D!0)%3Ba%26%26!d.checked%26%26(f%3D!0)%3Bf%26%26(d%3DgetControllerForCounty(d)%2CfindTieBid(d)%2Cd.btnBidUp.click()%2Cc%26%26d.btnSave.click())%7D%7Dfunction%20tieCounty(b%2Ca)%7BfindTieBid(b)%3Ba%26%26b.btnSave.click()%7Dfunction%20tieAll(b%2Ca%2Cc)%7Bvar%20e%3Ddocument.querySelectorAll(%22.subscription-status%22)%3Be%3D%24jscomp.makeIterator(e)%3Bfor(var%20d%3De.next()%3B!d.done%3Bd%3De.next())%7Bd%3Dd.value%3Bvar%20f%3D!1%3Bb%26%26d.checked%26%26(f%3D!0)%3Ba%26%26!d.checked%26%26(f%3D!0)%3Bf%26%26(d%3DgetControllerForCounty(d)%2CfindTieBid(d)%2Cc%26%26d.btnSave.click())%7D%7Dvar%20keepWinning%3Dfunction()%7BwinCounty(washington%2C!0)%3BwinCounty(marion%2C!0)%3BtieCounty(clackamas%2C!1)%3BtieCounty(cascade%2C!1)%3Bconsole.log(%22Still%20winning%20at%20%22%2Bnew%20Date)%7D%2Ccascade%3DgetCountyInfo(%2284034%22)%2Cmarion%3DgetCountyInfo(%2287833%22)%2Cwashington%3DgetCountyInfo(%2284035%22)%2Cclackamas%3DgetCountyInfo(%2284037%22)%3BkeepWinning()%3Bvar%20interval%3DsetInterval(keepWinning%2C3E5)%3Bvoid+0 \ No newline at end of file diff --git a/index.htm b/index.htm new file mode 100644 index 0000000..06bf3e7 --- /dev/null +++ b/index.htm @@ -0,0 +1,12 @@ + + + + +

AlwaysWin-ntsmhf Bookmarklet

+ +alwayswin-ntsmhf
+Drag & drop the above link into your bookmarks to save it.
+Compiled JavaScript thanks to Google's Closure Compiler. +
+ + \ No newline at end of file