rentmasseur-optimizer / _set_availability.py
github-actions[bot]
Auto-deploy 2026-07-27-09:37:04
1f355ea
Raw
History Blame Contribute Delete
6.63 kB
#!/usr/bin/env python3
"""Set availability to 24/7 via undetected-chromedriver."""
import time, os, json
import undetected_chromedriver as uc
from dotenv import load_dotenv
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from datetime import datetime, timezone
load_dotenv(os.path.join(os.path.dirname(__file__), ".env"))
load_dotenv()
USERNAME = os.getenv("RENTMASSEUR_USERNAME", "")
PASSWORD = os.getenv("RENTMASSEUR_PASSWORD", "")
options = uc.ChromeOptions()
options.add_argument("--window-size=1280,900")
options.add_argument("--disable-blink-features=AutomationControlled")
driver = uc.Chrome(options=options, version_main=149)
try:
print("[1] Login...")
driver.get("https://rentmasseur.com/login")
time.sleep(6)
driver.execute_script("""
const pwd = document.querySelector('input[type="password"]');
const user = document.querySelector('input[type="text"], input[type="email"]');
const ns = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
if (user) { ns.call(user, arguments[0]); user.dispatchEvent(new Event('input', {bubbles: true})); }
if (pwd) { ns.call(pwd, arguments[1]); pwd.dispatchEvent(new Event('input', {bubbles: true})); }
""", USERNAME, PASSWORD)
time.sleep(1)
driver.find_element(By.CSS_SELECTOR, 'input[type="password"]').send_keys(Keys.ENTER)
time.sleep(5)
print(f" URL: {driver.current_url}")
print("\n[2] Setting availability...")
driver.get("https://rentmasseur.com/settings/travels")
time.sleep(5)
# Find availability controls
info = driver.execute_script("""
const r = {selects: [], buttons: [], inputs: [], textareas: []};
document.querySelectorAll('select').forEach(s => {
r.selects.push({id: s.id, name: s.name, options: Array.from(s.options).map(o => o.text).join('|'), value: s.value});
});
document.querySelectorAll('button').forEach(b => r.buttons.push({text: b.innerText.trim(), type: b.type, id: b.id}));
document.querySelectorAll('input').forEach(i => r.inputs.push({type: i.type, id: i.id, name: i.name, value: (i.value||'').substring(0,30), checked: i.checked}));
document.querySelectorAll('textarea').forEach(t => r.textareas.push({id: t.id, name: t.name, value: (t.value||'').substring(0,50)}));
return r;
""")
print(f" Selects: {len(info['selects'])}")
for s in info['selects']:
print(f" id={s['id']} name={s['name']} value={s['value']} options={s['options'][:80]}")
print(f" Buttons: {len(info['buttons'])}")
for b in info['buttons']:
print(f" {b['text']} type={b['type']}")
print(f" Inputs: {len(info['inputs'])}")
for i in info['inputs']:
print(f" type={i['type']} id={i['id']} name={i['name']} value={i['value']} checked={i['checked']}")
# Try to set availability
set_result = driver.execute_script("""
// Look for availability select or radio
const selects = Array.from(document.querySelectorAll('select'));
const availSelect = selects.find(s => {
const opts = Array.from(s.options).map(o => o.text.toLowerCase());
return opts.some(o => o.includes('available'));
});
if (availSelect) {
const availOpt = Array.from(availSelect.options).find(o =>
o.text.toLowerCase().includes('available') && !o.text.toLowerCase().includes('not'));
if (availOpt) {
availSelect.value = availOpt.value;
availSelect.dispatchEvent(new Event('change', {bubbles: true}));
return {method: 'select', value: availOpt.text};
}
}
// Look for radio buttons
const radios = Array.from(document.querySelectorAll('input[type="radio"]'));
const availRadio = radios.find(r => /avail/i.test(r.name + r.id + (r.value||'')));
if (availRadio) {
availRadio.click();
return {method: 'radio', value: availRadio.value};
}
// Look for toggle/checkbox
const checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]'));
const availCheckbox = checkboxes.find(c => /avail/i.test(c.name + c.id));
if (availCheckbox && !availCheckbox.checked) {
availCheckbox.click();
return {method: 'checkbox', checked: true};
}
return {error: 'no_availability_control'};
""")
print(f"\n Set result: {set_result}")
if 'error' not in set_result:
time.sleep(1)
# Save
saved = driver.execute_script("""
const btns = Array.from(document.querySelectorAll('button, input[type="submit"]'));
const sb = btns.find(b => /save|update|submit|apply|confirm/i.test((b.innerText||'')+' '+(b.value||'')));
if (sb) { sb.click(); return {ok: true, text: sb.innerText}; }
return {ok: false};
""")
print(f" Save: {saved}")
time.sleep(3)
# Write receipt
receipts_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "receipts")
os.makedirs(receipts_dir, exist_ok=True)
receipt = {"action": "set_availability", "status": "available_24_7", "success": True, "timestamp": datetime.now(timezone.utc).isoformat(), "method": "undetected-chromedriver"}
rpath = os.path.join(receipts_dir, f"availability_{receipt['timestamp'].replace(':','-')}.json")
with open(rpath, "w") as f:
json.dump(receipt, f, indent=2)
print(f"\n=== AVAILABILITY SET === Receipt: {rpath}")
else:
# Try the travels page or other settings pages
print(" Trying /settings page directly...")
driver.get("https://rentmasseur.com/settings")
time.sleep(4)
driver.save_screenshot("/Users/alep/Downloads/rentmasseur-optimizer/settings_avail.png")
# Check for availability toggle on main settings
toggles = driver.execute_script("""
return Array.from(document.querySelectorAll('input[type="checkbox"], .toggle, .switch, [role="switch"]')).map(e => ({
type: e.type, id: e.id, name: e.name, checked: e.checked,
label: e.closest('label') ? e.closest('label').innerText : (e.parentElement ? e.parentElement.innerText : '')
}));
""")
print(f" Toggles: {len(toggles)}")
for t in toggles:
print(f" {t}")
finally:
driver.quit()
print("\nDone.")