Skip to content

Commit

Permalink
Merge pull request dgrnbrg#6 from aysylu/main
Browse files Browse the repository at this point in the history
  • Loading branch information
dgrnbrg authored Apr 29, 2024
2 parents 27af08e + e69e49f commit 392b19d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 19 deletions.
43 changes: 25 additions & 18 deletions goportparking.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException

import hassapi as hass
import traceback
import adbase as ad

JS_WAIT = 1
WEB_WAIT = 5

class GoPortParkingController(hass.Hass):
def initialize(self):
chrome_options = Options()
Expand All @@ -35,26 +39,13 @@ def filter_quick_buy_button(x):
return False
self.listen_event(self.book_daily, "call_service", domain="button", service="press", service_data=filter_quick_buy_button)
self.run_daily(self.reset_state, '3:00:00')
self.listen_state(self.parking_pass_email_cb, self.args['parking_pass_email_sensor'], attribute='subject')
self.pending_plates = []

def terminate(self):
try:
self.driver.close()
except Exception:
self.log(f"failed to terminate properly: {traceback.format_exc()}")

def parking_pass_email_cb(self, entity, attr, old, new, kwargs):
if len(self.pending_plates) > 0:
plate = self.pending_plates.pop()
entity_id = f"button.quick_buy_daily_{plate}"
entity = self.get_entity(entity_id)
if new not in ['RPP Approved', 'Payment Processed']:
self.log(f"Unexpected email from RPP email: {new}")
entity.set_state(state='error', attributes={'detail': 'Unexpected email from parking: {new}'})
else:
entity.set_state(state='successfully_purchased', attributes={'detail': 'Purchase successfully completed.'})

def reset_state(self, kwargs):
for plate in self.args['plates']:
entity_id = f"button.quick_buy_daily_{plate}"
Expand All @@ -74,7 +65,7 @@ def book_daily(self, event_name, data, kwargs):
self.get_entity(entity).set_state(state='opening_portal', attributes={'detail': 'Opening portal'})
self.log(f"buying daily: navigating to login")
self.driver.get("https://goportparking.org/rppportal/login.xhtml")
time.sleep(5)
time.sleep(WEB_WAIT)
self.log(f"buying daily: logging in")
username = self.driver.find_element(By.ID, "username")
username.clear()
Expand All @@ -84,20 +75,36 @@ def book_daily(self, event_name, data, kwargs):
password.send_keys(self.args['password'])
self.driver.find_element(By.ID, "login").click()
self.get_entity(entity).set_state(state='logging_in', attributes={'detail': 'Logging in...'})
time.sleep(5)
time.sleep(WEB_WAIT)
if self.driver.current_url != 'https://goportparking.org/rppportal/index.xhtml':
self.log(f"Login seems to have failed")
self.get_entity(entity).set_state(state='login_failed', attributes={'detail': 'Login failed'})
return
self.log(f"buying daily: activating quick-buy (on url {self.driver.current_url})")
self.get_entity(entity).set_state(state='purchasing_daily', attributes={'detail': 'Purchasing daily pass...'})
quick_buy = self.driver.find_element(By.PARTIAL_LINK_TEXT, plate)
try:
quick_buy = self.driver.find_element(By.PARTIAL_LINK_TEXT, plate)
except NoSuchElementException:
drop_down = self.driver.find_element(By.CLASS_NAME, 'caret')
drop_down.click()
time.sleep(JS_WAIT)
quick_buy = self.driver.find_element(By.PARTIAL_LINK_TEXT, plate)
quick_buy.click()
time.sleep(5)
time.sleep(WEB_WAIT)
self.log(f"buying daily: confirming quick-buy")
self.get_entity(entity).set_state(state='confirming_purchase', attributes={'detail': 'Confirming purchase...'})
quick_buy_confirm = self.driver.find_element(By.XPATH, "//span[@id='quickBuyConfirmPanel']//input[@Value='Yes']")
quick_buy_confirm.click()
print(f"bought the daily pass (confirm={quick_buy_confirm})")
self.pending_plates.append(plate)

time.sleep(WEB_WAIT)
try:
xpath = f'//div[contains(@class, "panel") and .//h3[contains(text(), "Your RPPs")] and .//li[contains(@class, "active") and ./a[contains(text(), "Current RPPs")]] and .//td[./span[contains(text(), "Plate")] and ./span[contains(text(), "{plate}") and contains(@class, "text-success")]]]'
self.log(f"Find element by xpath {xpath}")
self.driver.find_element(By.XPATH, xpath)
self.log(f"Found active parking pass on RPP portal for {plate}")
self.get_entity(entity).set_state(state='successfully_purchased', attributes={'detail': 'Purchase successfully completed.'})
except NoSuchElementException as nse:
self.log(f"Unexpected state from RPP portal for {plate}: {nse}")
self.get_entity(entity).set_state(state='error', attributes={'detail': 'No active parking passes, check the website.'})

2 changes: 1 addition & 1 deletion lights.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def match(service_data):

@ad.app_lock
def service_snoop(self, event_name, data, kwargs):
if data['domain'] != 'light' and data['domain'] != 'button' and data['domain'] != 'input_boolean':
if 'domain' not in data or data['domain'] != 'light' and data['domain'] != 'button' and data['domain'] != 'input_boolean':
return
#print(f"service snooped {data}")
endogenous = data['metadata']['context']['user_id'] == self.user_id
Expand Down

0 comments on commit 392b19d

Please sign in to comment.