From 511b43a9f14c648f3e6a55fe13b983b32b92b378 Mon Sep 17 00:00:00 2001 From: esir Date: Sat, 9 Nov 2019 09:50:50 +0300 Subject: [PATCH] Automatically downloads chrome driver for users according the their os platform --- deletefb/tools/chrome_driver.py | 111 ++++++++++++++++++++++++++++++++ deletefb/tools/common.py | 10 +-- deletefb/tools/login.py | 17 ++--- 3 files changed, 122 insertions(+), 16 deletions(-) create mode 100644 deletefb/tools/chrome_driver.py diff --git a/deletefb/tools/chrome_driver.py b/deletefb/tools/chrome_driver.py new file mode 100644 index 0000000..ddd8fc1 --- /dev/null +++ b/deletefb/tools/chrome_driver.py @@ -0,0 +1,111 @@ +import re +import zipfile +import os, sys, stat, platform +from urllib.request import urlretrieve + +from clint.textui import puts, colored +import progressbar + +from selenium import webdriver +from selenium.webdriver.chrome.options import Options + +from .common import NO_CHROME_DRIVER + + +def extract_zip(filename): + """ + Uses zipfile package to extract a single zipfile + :param filename: + :return: new filename + """ + try: + file = zipfile.ZipFile(filename, 'r') + except FileNotFoundError: + puts(colored.red(f"{filename} Does not exist")) + sys.exit() + + # Save the name of the new file + new_file_name = file.namelist()[0] + + # Extract the file and make it executable + file.extractall() + + driver_stat = os.stat(new_file_name) + os.chmod(new_file_name, driver_stat.st_mode | stat.S_IEXEC) + + file.close() + os.remove(filename) + return new_file_name + + +def setup_selenium(driver_path, options): + # Configures selenium to use a custom path + driver = webdriver.Chrome(executable_path=driver_path, options=options) + return driver + + +def get_webdriver(): + """ + Ensure a webdriver is available + If Not, Download it. + """ + cwd = os.listdir(os.getcwd()) + webdriver_regex = re.compile('chromedriver') + web_driver = list(filter(webdriver_regex.match, cwd)) + + if web_driver: + # check if a extracted copy already exists + if not os.path.isfile('chromedriver'): + # Extract file + extract_zip(web_driver[0]) + + return os.getcwd() + '/chromedriver' + + else: + # Download it according to the current machine + webdrivers = ['https://chromedriver.storage.googleapis.com/78.0.3904.70/chromedriver_mac64.zip', + 'https://chromedriver.storage.googleapis.com/78.0.3904.70/chromedriver_linux64.zip', + 'https://chromedriver.storage.googleapis.com/78.0.3904.70/chromedriver_win32.zip' + ] + os_platform = platform.system() + if os_platform == 'Darwin': + chrome_webdriver = webdrivers[0] + elif os_platform == 'Linux': + chrome_webdriver = webdrivers[1] + elif os_platform == 'Windows': + chrome_webdriver = webdrivers[2] + else: + raise Exception("Unknown Operating system platform") + + global total_size + + def show_progress(*res): + global total_size + pbar = None + downloaded = 0 + block_num, block_size, total_size = res + + if not pbar: + pbar = progressbar.ProgressBar(maxval=total_size) + pbar.start() + downloaded += block_num * block_size + + if downloaded < total_size: + pbar.update(downloaded) + else: + pbar.finish() + + puts(colored.yellow("Downloading Chrome Webdriver")) + file_name = chrome_webdriver.split('/')[-1] + response = urlretrieve(chrome_webdriver, file_name, show_progress) + + if int(response[1].get('Content-Length')) == total_size: + puts(colored.green(f"DONE!")) + + return os.getcwd() + '/' + extract_zip(file_name) + else: + puts(colored.red("An error Occurred While trying to download the driver.")) + # remove the downloaded file and exit + os.remove(file_name) + sys.stderr.write(NO_CHROME_DRIVER) + sys.exit(1) diff --git a/deletefb/tools/common.py b/deletefb/tools/common.py index de0d679..bb24989 100644 --- a/deletefb/tools/common.py +++ b/deletefb/tools/common.py @@ -5,15 +5,13 @@ from selenium.webdriver.common.by import By from selenium.common.exceptions import ( NoSuchElementException, StaleElementReferenceException, - TimeoutException, - JavascriptException + TimeoutException ) import json import logging import logging.config import os -import pendulum SELENIUM_EXCEPTIONS = ( NoSuchElementException, @@ -21,12 +19,14 @@ SELENIUM_EXCEPTIONS = ( TimeoutException ) + def click_button(driver, el): """ Click a button using Javascript """ driver.execute_script("arguments[0].click();", el) + def scroll_to(driver, el): """ Scroll an element into view, using JS @@ -36,6 +36,7 @@ def scroll_to(driver, el): except SELENIUM_EXCEPTIONS: return + def logger(name): """ Args: @@ -66,7 +67,8 @@ def wait_xpath(driver, expr): except SELENIUM_EXCEPTIONS: return + NO_CHROME_DRIVER = """ -You need to install the chromedriver for Selenium\n +You need to manually install the chromedriver for Selenium\n Please see this link https://github.com/weskerfoot/DeleteFB#how-to-use-it\n """ diff --git a/deletefb/tools/login.py b/deletefb/tools/login.py index 772b53e..2d3f39c 100644 --- a/deletefb/tools/login.py +++ b/deletefb/tools/login.py @@ -1,11 +1,11 @@ -from .common import NO_CHROME_DRIVER from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.chrome.options import Options -from seleniumrequests import Chrome -import sys import time +from .chrome_driver import get_webdriver, setup_selenium + + def login(user_email_address, user_password, is_headless, @@ -34,15 +34,8 @@ def login(user_email_address, chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('log-level=2') - try: - driver = Chrome(options=chrome_options) - except Exception as e: - # The user does not have chromedriver installed - # Tell them to install it - sys.stderr.write(str(e)) - sys.stderr.write(NO_CHROME_DRIVER) - sys.exit(1) - + driver_path = get_webdriver() + driver = setup_selenium(driver_path, chrome_options) driver.implicitly_wait(10) driver.get("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110")