55
66"""
77
8+ import binascii
89import logging
910from json import dumps , loads
1011
1112import os
1213import shutil
1314import tempfile
15+ from Crypto .Cipher import AES
16+ from axolotl .kdf .hkdfv3 import HKDFv3
17+ from axolotl .util .byteutil import ByteUtil
18+ from base64 import b64decode
19+ from io import BytesIO
1420from selenium import webdriver
1521from selenium .common .exceptions import NoSuchElementException
1622from selenium .webdriver .common .by import By
1925from selenium .webdriver .support import expected_conditions as EC
2026from selenium .webdriver .support .ui import WebDriverWait
2127
22- from webwhatsapi .objects .chat import factory_chat , UserChat , Chat
23- from webwhatsapi .objects .message import factory_message , MessageGroup
24- from .consts import Selectors , URL
28+ from .objects .chat import UserChat , factory_chat
2529from .objects .contact import Contact
30+ from .objects .message import MessageGroup , factory_message
2631from .wapi_js_wrapper import WapiJsWrapper
2732
2833__version__ = '2.0.2'
@@ -141,10 +146,11 @@ def set_proxy(self, proxy):
141146 self ._profile .set_preference ("network.proxy.ssl_port" , int (proxy_port ))
142147
143148 def __init__ (self , client = "firefox" , username = "API" , proxy = None , command_executor = None , loadstyles = False ,
144- profile = None , headless = False , autoconnect = True , logger = None ):
149+ profile = None , headless = False , autoconnect = True , logger = None , extra_params = None ):
145150 "Initialises the webdriver"
146151
147152 self .logger = logger or self .logger
153+ extra_params = extra_params or {}
148154
149155 if profile is not None :
150156 self ._profile_path = profile
@@ -161,7 +167,7 @@ def __init__(self, client="firefox", username="API", proxy=None, command_executo
161167 self ._profile = webdriver .FirefoxProfile (self ._profile_path )
162168 else :
163169 self ._profile = webdriver .FirefoxProfile ()
164- if loadstyles == False :
170+ if not loadstyles :
165171 # Disable CSS
166172 self ._profile .set_preference ('permissions.default.stylesheet' , 2 )
167173 # Disable images
@@ -183,21 +189,22 @@ def __init__(self, client="firefox", username="API", proxy=None, command_executo
183189 capabilities ['webStorageEnabled' ] = True
184190
185191 self .logger .info ("Starting webdriver" )
186- self .driver = webdriver .Firefox (capabilities = capabilities , options = options )
192+ self .driver = webdriver .Firefox (capabilities = capabilities , options = options , ** extra_params )
187193
188194 elif self .client == "chrome" :
189195 self ._profile = webdriver .chrome .options .Options ()
190196 if self ._profile_path is not None :
191197 self ._profile .add_argument ("user-data-dir=%s" % self ._profile_path )
192198 if proxy is not None :
193199 profile .add_argument ('--proxy-server=%s' % proxy )
194- self .driver = webdriver .Chrome (chrome_options = self ._profile )
200+ self .driver = webdriver .Chrome (chrome_options = self ._profile , ** extra_params )
195201
196202 elif client == 'remote' :
197203 capabilities = DesiredCapabilities .FIREFOX .copy ()
198204 self .driver = webdriver .Remote (
199205 command_executor = command_executor ,
200- desired_capabilities = capabilities
206+ desired_capabilities = capabilities ,
207+ ** extra_params
201208 )
202209
203210 else :
@@ -395,5 +402,32 @@ def group_get_admins(self, group_id):
395402 for admin_id in admin_ids :
396403 yield self .get_contact_from_id (admin_id )
397404
405+ def download_file (self , url ):
406+ return b64decode (self .wapi_functions .downloadFile (url ))
407+
408+ def download_media (self , media_msg ):
409+ try :
410+ if media_msg .content :
411+ return BytesIO (b64decode (self .content ))
412+ except AttributeError :
413+ pass
414+
415+ file_data = self .download_file (media_msg .client_url )
416+
417+ media_key = b64decode (media_msg .media_key )
418+ derivative = HKDFv3 ().deriveSecrets (media_key ,
419+ binascii .unhexlify (media_msg .crypt_keys [media_msg .type ]),
420+ 112 )
421+
422+ parts = ByteUtil .split (derivative , 16 , 32 )
423+ iv = parts [0 ]
424+ cipher_key = parts [1 ]
425+ e_file = file_data [:- 10 ]
426+
427+ AES .key_size = 128
428+ cr_obj = AES .new (key = cipher_key , mode = AES .MODE_CBC , IV = iv )
429+
430+ return BytesIO (cr_obj .decrypt (e_file ))
431+
398432 def quit (self ):
399433 self .driver .quit ()
0 commit comments