Automate Scrubbing your Facebook Presence
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

166 lines
5.5 KiB

from ..exceptions import UnknownOSException, ChromeError
from .common import NO_CHROME_DRIVER
from clint.textui import puts, colored
from selenium import webdriver
from shutil import which
from subprocess import check_output
from urllib.request import urlretrieve
from appdirs import AppDirs
from ..version import version
from os.path import exists
import os, sys, stat, platform
import progressbar
import re
import zipfile
import requests
import pathlib
cache_dir = AppDirs("DeleteFB", version=version).user_cache_dir
try:
pathlib.Path(cache_dir).mkdir(parents=True, exist_ok=True)
except FileExistsError:
pass
def extract_zip(filename, chrome_maj_version):
"""
Uses zipfile package to extract a single zipfile
:param filename:
:return: new filename
"""
# Remove any leftover unversioned chromedriver
try:
os.remove(f"{cache_dir}/chromedriver")
except FileNotFoundError:
pass
try:
_file = zipfile.ZipFile(filename, 'r')
except FileNotFoundError:
puts(colored.red(f"{filename} Does not exist"))
sys.exit(1)
# Save the name of the new file
new_file_name = f"{cache_dir}/{_file.namelist()[0] + chrome_maj_version}"
# Extract the file and make it executable
_file.extractall(path=cache_dir)
# Rename the filename to a versioned one
os.rename(f"{cache_dir}/chromedriver", f"{cache_dir}/chromedriver{chrome_maj_version}")
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(options, chrome_binary_path):
try:
# try letting Selenium find the driver (in PATH)
return webdriver.Chrome(options=options)
except WebDriverException:
# Configures selenium to use a custom path
driver_path = get_webdriver(chrome_binary_path)
return webdriver.Chrome(executable_path=driver_path, options=options)
def parse_version(output):
"""
Attempt to extract version number from chrome version string.
"""
return [c for c in re.split('([0-9]+)\.?', output.decode("utf-8")) if all(d.isdigit() for d in c) and c][0]
def get_chrome_version(chrome_binary_path=None):
"""
Extract the chrome major version.
"""
driver_locations = [which(loc) for loc in ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "chrome.exe"]]
for location in driver_locations:
if location:
return parse_version(check_output([location, "--version"]).strip())
return None
def construct_driver_url(chrome_binary_path=None):
"""
Construct a URL to download the Chrome Driver.
"""
platform_string = platform.system()
chrome_drivers = {
"Windows" : "https://chromedriver.storage.googleapis.com/{0}/chromedriver_win32.zip",
"Darwin" : "https://chromedriver.storage.googleapis.com/{0}/chromedriver_mac64.zip",
"Linux" : "https://chromedriver.storage.googleapis.com/{0}/chromedriver_linux64.zip"
}
version = get_chrome_version()
if version is None:
raise ChromeError("Chrome version not found")
latest_release_url = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_{0}".format(version)
return version, chrome_drivers.get(platform_string).format(requests.get(latest_release_url).text)
# First, construct a LATEST_RELEASE URL using Chrome's major version number.
# For example, with Chrome version 73.0.3683.86, use URL "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_73".
# Try to download a small file from this URL. If it successful, the file contains the ChromeDriver version to use.
# If the above step failed, reduce the Chrome major version by 1 and try again.
# For example, with Chrome version 75.0.3745.4, use URL "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_74"
# to download a small file, which contains the ChromeDriver version to use.
# You can also use ChromeDriver Canary build.
def get_webdriver(chrome_binary_path):
"""
Ensure a webdriver is available
If Not, Download it.
"""
# Download it according to the current machine
chrome_maj_version, chrome_webdriver = construct_driver_url(chrome_binary_path)
driver_path = f"{cache_dir}/chromedriver{chrome_maj_version}"
if exists(driver_path):
return driver_path
if not chrome_webdriver:
raise UnknownOSException("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 = f"{cache_dir}/{chrome_webdriver.split('/')[-1]}"
response = urlretrieve(chrome_webdriver, file_name, show_progress)
if int(response[1].get("Content-Length")) == total_size:
puts(colored.green("Completed downloading the Chrome Driver."))
return extract_zip(file_name, chrome_maj_version)
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)