Skip to content

Commit

Permalink
add async
Browse files Browse the repository at this point in the history
  • Loading branch information
3mora2 committed Mar 25, 2024
1 parent 023668d commit b124103
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 156 deletions.
79 changes: 0 additions & 79 deletions WPP_Whatsapp/PlaywrightSafeThread/__init__.py

This file was deleted.

2 changes: 1 addition & 1 deletion WPP_Whatsapp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from WPP_Whatsapp.controllers.browser import ThreadsafeBrowser
from WPP_Whatsapp.api.Whatsapp import Whatsapp
from WPP_Whatsapp.controllers.browser import Browser
from WPP_Whatsapp.controllers.initializer import Create


42 changes: 21 additions & 21 deletions WPP_Whatsapp/api/layers/HostLayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from playwright.async_api import Page
from WPP_Whatsapp.api.const import whatsappUrl, Logger
from WPP_Whatsapp.api.helpers.function import asciiQr
from WPP_Whatsapp.PlaywrightSafeThread import ThreadsafeBrowser
from WPP_Whatsapp.controllers.browser import ThreadsafeBrowser
from WPP_Whatsapp.api.helpers.jsFunction import setInterval
from WPP_Whatsapp.api.helpers.wa_version import getPageContent

Expand Down Expand Up @@ -121,8 +121,8 @@ async def start(self):
############################### initWhatsapp ####################################################
async def initWhatsapp(self):
# await page.setUserAgent(useragentOverride);
# self.logger.info(f'{self.session}: unregisterServiceWorker')
# await self.unregisterServiceWorker()
self.logger.info(f'{self.session}: unregisterServiceWorker')
await self.unregisterServiceWorker()
if self.version:
self.logger.info(f'{self.session}: Setting WhatsApp WEB version to {self.version}')
await self.setWhatsappVersion(self.version)
Expand All @@ -135,6 +135,11 @@ async def initWhatsapp(self):
async def unregisterServiceWorker(self):
try:
await self.ThreadsafeBrowser.page_evaluate("""() => {
setInterval(() => {
window.onerror = console.error;
window.onunhandledrejection = console.error;
}, 500);
// Remove existent service worker
navigator.serviceWorker
.getRegistrations()
Expand All @@ -148,14 +153,9 @@ async def unregisterServiceWorker(self):
// Disable service worker registration
// @ts-ignore
navigator.serviceWorker.register = new Promise(() => {});
setInterval(() => {
window.onerror = console.error;
window.onunhandledrejection = console.error;
}, 500);
}""")
except:
Logger.exception("unregisterServiceWorker")
pass

async def setWhatsappVersion(self, version):
body = ""
Expand Down Expand Up @@ -364,7 +364,7 @@ def waitForPageLoad(self):
# TODO::
self.ThreadsafeBrowser.sleep(.2)

self.ThreadsafeBrowser.sync_page_wait_for_function("() => WPP.isReady")
self.ThreadsafeBrowser.page_wait_for_function_sync("() => WPP.isReady")

async def waitForPageLoad_(self):
while not self.isInjected:
Expand Down Expand Up @@ -507,11 +507,11 @@ def waitForLogin(self):

def getHostDevice(self):
"""@returns Current host device details"""
return self.ThreadsafeBrowser.sync_page_evaluate("() => WAPI.getHost()")
return self.ThreadsafeBrowser.page_evaluate_sync("() => WAPI.getHost()")

def getWid(self):
"""@returns Current wid connected"""
return self.ThreadsafeBrowser.sync_page_evaluate("() => WAPI.getWid()")
return self.ThreadsafeBrowser.page_evaluate_sync("() => WAPI.getWid()")

async def getWAVersion(self):
"""Retrieves WA version"""
Expand All @@ -523,26 +523,26 @@ async def getWAJSVersion(self):
return await self.ThreadsafeBrowser.page_evaluate("() => WPP.version")

def getConnectionState(self):
return self.ThreadsafeBrowser.sync_page_evaluate("() => {return WPP.whatsapp.Socket.state;}")
return self.ThreadsafeBrowser.page_evaluate_sync("() => {return WPP.whatsapp.Socket.state;}")

def isConnected(self):
"""Retrieves if the phone is online. Please note that this may not be real time."""
return self.ThreadsafeBrowser.sync_page_evaluate("() => WAPI.isConnected()")
return self.ThreadsafeBrowser.page_evaluate_sync("() => WAPI.isConnected()")

def isLoggedIn(self):
return self.ThreadsafeBrowser.sync_page_evaluate("() => WAPI.isLoggedIn()")
return self.ThreadsafeBrowser.page_evaluate_sync("() => WAPI.isLoggedIn()")

def getBatteryLevel(self):
return self.ThreadsafeBrowser.sync_page_evaluate("() => WAPI.getBatteryLevel()")
return self.ThreadsafeBrowser.page_evaluate_sync("() => WAPI.getBatteryLevel()")

def startPhoneWatchdog(self, interval=15000):
return self.ThreadsafeBrowser.sync_page_evaluate("(interval) => WAPI.startPhoneWatchdog(interval)", interval)
return self.ThreadsafeBrowser.page_evaluate_sync("(interval) => WAPI.startPhoneWatchdog(interval)", interval)

def stopPhoneWatchdog(self):
return self.ThreadsafeBrowser.sync_page_evaluate("() => WAPI.stopPhoneWatchdog()")
return self.ThreadsafeBrowser.page_evaluate_sync("() => WAPI.stopPhoneWatchdog()")

def isMultiDevice(self):
return self.ThreadsafeBrowser.sync_page_evaluate("() => WPP.conn.isMultiDevice()")
return self.ThreadsafeBrowser.page_evaluate_sync("() => WPP.conn.isMultiDevice()")

async def isAuthenticated(self):
try:
Expand All @@ -557,7 +557,7 @@ def sync_isAuthenticated(self):
try:
if self.page.is_closed():
return False
return self.ThreadsafeBrowser.sync_page_evaluate("() => WPP.conn.isRegistered()")
return self.ThreadsafeBrowser.page_evaluate_sync("() => WPP.conn.isRegistered()")
except Exception as e:
self.logger.debug(e)
return False
Expand Down Expand Up @@ -613,7 +613,7 @@ async def isInsideChat(self):
return result if result else False

def sync_isInsideChat(self):
result = self.ThreadsafeBrowser.sync_page_evaluate("() => WPP.conn.isMainReady()")
result = self.ThreadsafeBrowser.page_evaluate_sync("() => WPP.conn.isMainReady()")
return result if result else False

async def inject_api(self):
Expand Down
88 changes: 48 additions & 40 deletions WPP_Whatsapp/controllers/browser.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,50 @@
import asyncio

from playwright.async_api import async_playwright, Playwright, BrowserContext, Page

from WPP_Whatsapp.api.const import useragentOverride


class Browser:
session: str
playwright: "Playwright"
browser: "BrowserContext"
page: "Page"

def __init__(self, user_data_dir: str = "", headless: bool = False, *args, **kwargs):
self.user_data_dir = user_data_dir
self.loop = kwargs.get("loop")
if not self.loop:
raise Exception("Not Add Loop")
asyncio.set_event_loop(self.loop)
self.headless = headless

async def initBrowser(self):
self.playwright = await async_playwright().start()
self.browser = await self.playwright.chromium.launch_persistent_context(
self.user_data_dir, channel="chrome",
no_viewport=True,
headless=self.headless,
# args=chromiumArgs,
bypass_csp=True,
user_agent=useragentOverride
)

self.page = self.browser.pages[0] if self.browser.pages else await self.browser.new_page()

async def page_evaluate(self, expression, arg=None):
return await self.page.evaluate(expression, arg)

async def page_wait_for_function(self, expression, arg=None, timeout=None, polling=None):
return await self.page.wait_for_function(expression, arg=arg, timeout=timeout, polling=polling)

# if __name__ == '__main__':
# asyncio.run(Browser().initBrowser())
from PlaywrightSafeThread.browser.threadsafe_browser import ThreadsafeBrowser as Tb, BrowserName, SUPPORTED_BROWSERS, \
Logger
from playwright.async_api import Error


class ThreadsafeBrowser(Tb):
def __init__(
self,
no_context=False,
browser: BrowserName = "chromium",
stealthy: bool = False,
install: bool = False,
check_open_dir=True,
close_already_profile=True,
**kwargs
) -> None:
super().__init__(no_context=no_context,
browser=browser,
stealthy=stealthy,
install=install,
check_open_dir=check_open_dir,
close_already_profile=close_already_profile,
**kwargs)

def page_evaluate_sync(self, *args, timeout_=60, **kwargs, ):
try:
return super().page_evaluate_sync(*args, timeout_=60, **kwargs, )
except Error as error:
if "Execution context was destroyed, most likely because of a navigation" in error.message:
pass
elif "ReferenceError: WPP is not defined" in error.message:
pass
else:
raise error

async def expose_function(self, *args, **kwargs, ):
return await super().expose_function(*args, **kwargs, )

def sleep(self, val, timeout_=None):
try:
super().sleep(val, timeout_=timeout_)
except:
pass

def run_threadsafe(self, func, *args, timeout_=120, **kwargs, ):
if not asyncio.iscoroutine(func):
func = func(*args, **kwargs)
return super().run_threadsafe(func, timeout_=timeout_)
6 changes: 3 additions & 3 deletions WPP_Whatsapp/controllers/initializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import os
import types
from typing import Optional
from WPP_Whatsapp.PlaywrightSafeThread import SUPPORTED_BROWSERS
from WPP_Whatsapp.PlaywrightSafeThread import ThreadsafeBrowser
from WPP_Whatsapp.controllers.browser import SUPPORTED_BROWSERS
from WPP_Whatsapp.controllers.browser import ThreadsafeBrowser
from WPP_Whatsapp.api.Whatsapp import Whatsapp
from WPP_Whatsapp.api.const import Logger

Expand Down Expand Up @@ -78,7 +78,7 @@ def sync_close(self):
def _onStateChange(self, state):
self.state = state
if hasattr(self, "ThreadsafeBrowser") and not self.ThreadsafeBrowser.page.is_closed():
connected = self.ThreadsafeBrowser.sync_page_evaluate("() => WPP.conn.isRegistered()")
connected = self.ThreadsafeBrowser.page_evaluate_sync("() => WPP.conn.isRegistered()")
if not connected:
self.ThreadsafeBrowser.sleep(2)
if not self.waitLoginPromise:
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_create.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from WPP_Whatsapp import Whatsapp
from WPP_Whatsapp.PlaywrightSafeThread import ThreadsafeBrowser
from WPP_Whatsapp import ThreadsafeBrowser

session = "test"

Expand Down
10 changes: 5 additions & 5 deletions examples/start_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@
logger.setLevel(logging.DEBUG)


# Not Work Yet

async def main():
# start client with your session name
your_session_name = "test"
creator = Create(session=your_session_name, browser="chrome",
loop=asyncio.get_event_loop()) # , version="2.2409.2")
creator = Create(session=your_session_name, browser="chrome", version="2.2409.2")

client = await creator.start_()
# Now scan Whatsapp Qrcode in browser
Expand All @@ -21,7 +18,10 @@ async def main():
if creator.state != 'CONNECTED':
raise Exception(creator.state)

print(client.getWAVersion())
print(await client.getWAVersion())
client.sendText("201016788", "test")
await client.sendText_("201016788", "test")
await creator.close()


asyncio.run(main())
2 changes: 1 addition & 1 deletion examples/wa_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# start client with your session name
your_session_name = "test"
creator = Create(session=your_session_name, browser="chrome", version="2.2409.2")
creator = Create(session=your_session_name, browser="chrome", version="2.2409.2", autoClose=5)
client = creator.start()
# Now scan Whatsapp Qrcode in browser

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ typing_extensions
requests
node-semver
aiohttp
PlaywrightSafeThread
PlaywrightSafeThread>=0.5.2.1
6 changes: 2 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"the creation of any interaction, such as customer service, media sending, intelligence recognition "
"based on phrases artificial and many other things, use your imagination")

version = "0.1.9.6"
version = "0.2.0"

setup(
name="WPP_Whatsapp",
Expand All @@ -30,7 +30,7 @@
"playwright-stealth",
"node-semver",
"aiohttp",
"PlaywrightSafeThread"
"PlaywrightSafeThread>=0.5.2.1"
],
long_description=long_description,
long_description_content_type="text/markdown",
Expand All @@ -41,7 +41,5 @@
"Intended Audience :: Developers",
"Programming Language :: Python",
"Topic :: Software Development :: Libraries :: Python Modules",

],

)

0 comments on commit b124103

Please sign in to comment.