Skip to content

Commit

Permalink
Merge pull request #128 from jeslynlamxy/main
Browse files Browse the repository at this point in the history
Added new function, could be useful to some
  • Loading branch information
Kalebu authored Sep 16, 2023
2 parents 8b08d23 + 2ecd775 commit 4d50795
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions alright/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import sys
import time
import logging
import platformdirs
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
Expand All @@ -27,13 +26,13 @@


class WhatsApp(object):
def __init__(self, headless=False, browser=None, time_out=600):
def __init__(self, browser=None, time_out=600):
# CJM - 20220419: Added time_out=600 to allow the call with less than 600 sec timeout
# web.open(f"https://web.whatsapp.com/send?phone={phone_no}&text={quote(message)}")

self.BASE_URL = "https://web.whatsapp.com/"
self.suffix_link = "https://web.whatsapp.com/send?phone={mobile}&text&type=phone_number&app_absent=1"
self.headless= headless

if not browser:
browser = webdriver.Chrome(
ChromeDriverManager().install(),
Expand All @@ -56,14 +55,12 @@ def __init__(self, headless=False, browser=None, time_out=600):
@property
def chrome_options(self):
chrome_options = Options()
chrome_options.headless = self.headless
chrome_options.add_argument(
"--user-data-dir=" + platformdirs.user_data_dir("alright")
)
if sys.platform == "win32":
chrome_options.add_argument("--profile-directory=Default")
chrome_options.add_argument("--user-data-dir=C:/Temp/ChromeProfile")
else:
chrome_options.add_argument("start-maximized")
chrome_options.add_argument("--user-data-dir=./User_Data")
return chrome_options

def cli(self):
Expand Down Expand Up @@ -158,7 +155,7 @@ def find_by_username(self, username):
EC.presence_of_element_located(
(
By.XPATH,
'//*[@id="side"]/div[1]/div/div/div[2]/div/div[1]',
'//*[@id="app"]/div[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/div[2]/div[1]/div[2]',
)
)
)
Expand Down Expand Up @@ -265,7 +262,7 @@ def search_chat_by_name(self, query: str):
search_box.send_keys(Keys.ARROW_DOWN)
chat = self.browser.switch_to.active_element

# acceptable here as an exception!
# excepcitonally acceptable here!
time.sleep(1)
flag = False
prev_name = ""
Expand Down Expand Up @@ -423,10 +420,9 @@ def send_message1(self, mobile: str, message: str) -> str:
lambda ctrl_self: ctrl_self.find_elements(By.XPATH, nr_not_found_xpath)
or ctrl_self.find_elements(By.XPATH, inp_xpath)
)
msg = "0" # Not yet sent
# Iterate through the list of elements to test each if they are a textBox or a Button
for i in ctrl_element:
if i.get_attribute("role") == "textbox":
if i.aria_role == "textbox":
# This is a WhatsApp Number -> Send Message

for line in message.split("\n"):
Expand All @@ -440,7 +436,7 @@ def send_message1(self, mobile: str, message: str) -> str:
# Found alert issues when we send messages too fast, so I called the below line to catch any alerts
self.catch_alert()

elif i.get_attribute("role") == "button":
elif i.aria_role == "button":
# Did not find the Message Text box
# BUT we possibly found the XPath of the error "Phone number shared via url is invalid."
if i.text == "OK":
Expand All @@ -465,7 +461,7 @@ def send_message(self, message, timeout=0.0):
"""
try:
inp_xpath = (
'//*[@id="main"]/footer/div[1]/div/span[2]/div/div[2]/div[1]/div/div[1]'
'//*[@id="main"]/footer/div/div/span[2]/div/div[2]/div/div/div'
)
input_box = self.wait.until(
EC.presence_of_element_located((By.XPATH, inp_xpath))
Expand Down Expand Up @@ -499,6 +495,7 @@ def find_attachment(self):
clipButton.click()

def send_attachment(self):

# Waiting for the pending clock icon to disappear
self.wait.until_not(
EC.presence_of_element_located(
Expand All @@ -510,7 +507,7 @@ def send_attachment(self):
EC.presence_of_element_located(
(
By.XPATH,
"/html/body/div[1]/div/div/div[3]/div[2]/span/div/span/div/div/div[2]/div/div[2]/div[2]/div/div/span",
'//*[@id="app"]/div[1]/div/div[3]/div[2]/span/div/span/div/div/div[2]/div/div[2]/div[2]/div/div/span',
)
)
)
Expand Down Expand Up @@ -670,6 +667,30 @@ def close_when_message_successfully_sent(self):
self.browser.close()
LOGGER.info("Browser closed.")

def wait_until_message_successfully_sent(self):
"""wait_until_message_successfully_sent()
Waits until message is finished sending before continuing to next action.
Friendly contribution by @jeslynlamxy.
"""

LOGGER.info("Waiting for message status update to before continuing...")
try:
# Waiting for the pending clock icon shows and disappear
self.wait.until(
EC.presence_of_element_located(
(By.XPATH, '//*[@id="main"]//*[@data-icon="msg-time"]')
)
)
self.wait.until_not(
EC.presence_of_element_located(
(By.XPATH, '//*[@id="main"]//*[@data-icon="msg-time"]')
)
)
except (NoSuchElementException, Exception) as bug:
LOGGER.exception(f"Failed to send a message to {self.mobile} - {bug}")

def get_last_message_received(self, query: str):
"""get_last_message_received() [nCKbr]
Expand All @@ -679,7 +700,9 @@ def get_last_message_received(self, query: str):
query (string): query value to be located in the chat name
"""
try:

if self.find_by_username(query):

self.wait.until(
EC.presence_of_element_located(
(
Expand Down Expand Up @@ -749,6 +772,7 @@ def get_last_message_received(self, query: str):
header_group.get_attribute("data-testid") == "default-group"
and msg_sender.strip() in header_text.text
):

LOGGER.info(f"Message sender: {msg_sender}.")
elif (
msg_sender.strip() != msg[0].strip()
Expand Down

0 comments on commit 4d50795

Please sign in to comment.