login/logout mostly working.

Leonardo Barcaroli 2019-01-14 12:11:17 +01:00
parent 9c2599d954
commit 81418f3d2f
1 changed files with 100 additions and 16 deletions

View File

@ -1,7 +1,11 @@
# -*- coding: utf-8 -*-
"""Main module."""
"""
Operator is the main object that interacts with the foreign
service. It exposes methods to login, logout and check in and out.
"""
from datetime import datetime, timedelta
import logging
import os
import time
@ -15,10 +19,12 @@ from selenium.common.exceptions import WebDriverException, NoSuchElementExceptio
logging.basicConfig(
level=logging.INFO,
level=os.environ.get('BOTZ_LOGLEVEL', logging.INFO),
format='%(levelname)s: [%(name)s] -> %(message)s'
)
m_logger = logging.getLogger(__name__)
m_logger.debug("Init at debug")
def safely(f: T.Callable) -> T.Callable:
def _protection(self, *args, **kwargs):
@ -30,11 +36,43 @@ def safely(f: T.Callable) -> T.Callable:
return _protection
def _is_present(driver: wd.Firefox, xpath: str) -> bool:
try:
driver.find_element_by_xpath(xpath)
return True
except NoSuchElementException:
return False
def is_present(driver: wd.Firefox,
xpath: str,
timeout: T.Optional[timedelta]=None
) -> bool:
"""
Helper function. If an element is present in the DOM tree,
returns true. False otherwise.
"""
if timeout is None:
return _is_present(driver, xpath)
_now = datetime.now()
_elapsed = timedelta(seconds=0)
while _elapsed < timeout:
m_logger.debug("Not yet present: %s", xpath)
if _is_present(driver, xpath):
m_logger.debug("Present: %s", xpath)
return True
time.sleep(0.5)
_elapsed = datetime.now() - _now
return False
class Operator(wd.Firefox):
def __init__(
self,
base_uri: str,
name: str = None,
timeout: int=20,
proxy: T.Optional[T.Tuple[str, int]] = None,
headless: bool = True,
debug: bool = False,
@ -53,6 +91,7 @@ class Operator(wd.Firefox):
self.debug = debug
self.base_uri = base_uri
self.timeout = timedelta(seconds=timeout)
if proxy:
self.profile.set_preference('network.proxy.type', 1)
@ -72,15 +111,29 @@ class Operator(wd.Firefox):
self._checked_in = False
@safely
def do_login(self, user: str, password: str) -> None:
def login(self, user: str, password: str, force: bool=False) -> None:
"""
Do the login and proceed.
"""
if self._logged_in:
self.logger.warning("Already logged in: %s", user)
if not force:
return
self.logger.info("Forcing login: %s", user)
# Retrieve login page
#self.get('{}/jsp/login.jsp'.format(self.base_uri))
self.get(self.base_uri)
_correct_url = 'cpccchk' in self.current_url
_now = datetime.now()
_elapsed = timedelta(seconds=0)
while not _correct_url:
self.logger.debug("Not yet on login page: %s", self.current_url)
time.sleep(0.5)
_correct_url = 'cpccchk' in self.current_url
_elapsed = datetime.now() - _now
if _elapsed > self.timeout:
break
self.logger.debug("After login get: %s", self.current_url)
time.sleep(3)
time.sleep(1)
# Username
user_form = self.find_element_by_name('m_cUserName')
# Password
@ -91,24 +144,51 @@ class Operator(wd.Firefox):
user_form.send_keys(user)
pass_form.send_keys(password)
do_it = True
if self.debug:
_do_it = input("Really do the login? [y/n]").lower()
if self.debug and not force:
_do_it = input("Really do the login? [y/n] ").lower()
do_it = True if _do_it == "y" else False
if do_it:
self.logger.debug("Before clicking: %s", self.current_url)
login_butt.submit()
self.logger.debug("After clicking: %s", self.current_url)
time.sleep(5)
self.logger.debug("Login result: %s", self.title)
if 'Routine window' in self.title:
self.logger.debug("Reloading...")
self.refresh()
try:
self.find_element_by_xpath('//input[contains(@value, "Accedi")]')
# TODO: reckon a proper timeout mechanism
# based on cookie expire time
self.switch_to.alert.accept()
if is_present(self, '//a[contains(@class, "imgMenu_ctrl")]', self.timeout):
self._logged_in = True
self.logger.info("Login success for user: %s", user)
except NoSuchElementException as e:
self.logger.error("Login failed: %s", e)
else:
self.logger.error("Login failed: %s", user)
@safely
def logout(self, user: str, force: bool=False) -> None:
"""
Do the logout.
"""
if not self._logged_in:
self.logger.warning("Not yet logged in for user: %s", user)
if not force:
return
self.logger.info("Forcing logout: %s", user)
# Find the Profile menu and open it
profile_butt = self.find_element_by_xpath('//span[contains(@id, "imgNoPhotoLabel")]')
profile_butt.click()
time.sleep(1)
# Find the logout button
logout_butt = self.find_element_by_xpath('//input[@value="Logout user"]')
logout_butt.click()
if "jsp/usut_wapplogout_portlet.jsp" in self.current_url:
self.logger.info("User successfully logged out: %s", user)
else:
self.logger.warning("Logout failed: %s", user)
def logged_in(self):
"""
Check if already logged in. Checks if page is '/jsp/home.jsp'
and if login cookie is set (and not expired).
"""
pass
@safely
def check_in(self, force: bool=False) -> None:
@ -121,6 +201,8 @@ class Operator(wd.Firefox):
self.logger.warn("Already logged in!")
if not force:
return
enter_butt = self.find_element_by_xpath('//input[@value="Entrata"]')
enter_butt.submit()
# Click the check in button and change
# self._checked_in state in case of success
pass
@ -136,9 +218,11 @@ class Operator(wd.Firefox):
self.logger.warn("Not yet logged in!")
if not force:
return
exit_butt = self.find_element_by_xpath('//input[@value="Uscita"]')
exit_butt.submit()
# Click the check in button and change
# self._checked_in state in case of success
pass
def __del__(self):
def __del__(self) -> None:
self.quit()