diff --git a/deletefb/deletefb.py b/deletefb/deletefb.py index 6f670ca..b6cc483 100755 --- a/deletefb/deletefb.py +++ b/deletefb/deletefb.py @@ -1,10 +1,10 @@ -#! /usr/bin/env python +#!/usr/bin/env python import argparse import getpass +import sys +import os -from sys import exit -from os import environ from .tools.login import login from .tools.wall import delete_posts from .tools.likes import unlike_pages @@ -88,9 +88,9 @@ def run_delete(): args = parser.parse_args() if args.archive_off: - environ["DELETEFB_ARCHIVE"] = "false" + os.environ["DELETEFB_ARCHIVE"] = "false" else: - environ["DELETEFB_ARCHIVE"] = "true" + os.environ["DELETEFB_ARCHIVE"] = "true" if args.year and args.mode != "wall": @@ -113,7 +113,7 @@ def run_delete(): unlike_pages(driver) else: print("Please enter a valid mode") - exit(1) + sys.exit(1) if __name__ == "__main__": run_delete() diff --git a/deletefb/tools/common.py b/deletefb/tools/common.py index 50fb71d..e086df6 100644 --- a/deletefb/tools/common.py +++ b/deletefb/tools/common.py @@ -1,50 +1,59 @@ -from selenium.common.exceptions import (NoSuchElementException, - StaleElementReferenceException, - TimeoutException) -from time import sleep -from json import dumps +import json +import os from os.path import abspath, relpath, split -from os import environ +import time -SELENIUM_EXCEPTIONS = (NoSuchElementException, - StaleElementReferenceException, - TimeoutException) +from selenium.common.exceptions import ( + NoSuchElementException, + StaleElementReferenceException, + TimeoutException +) + + +SELENIUM_EXCEPTIONS = ( + NoSuchElementException, + StaleElementReferenceException, + TimeoutException +) def try_move(actions, el): for _ in range(10): try: actions.move_to_element(el).perform() except StaleElementReferenceException: - sleep(5) + time.sleep(5) continue def archiver(category): """ - category: the category of logs you want to log - return values: (log_file_handle, archiver) + Log content to file. Call using `archive("some content")` + + Args: + category: str The category of logs you want to log - call archiver like archive("some content") + Returns: + (log_file_handle, archiver) """ log_path = "{0}.log".format(abspath(relpath(split(category)[-1], "."))) log_file = open(log_path, mode="ta", buffering=1) def log(content, timestamp=False): - if environ.get("DELETEFB_ARCHIVE", "true") == "false": + if os.environ.get("DELETEFB_ARCHIVE", "true") == "false": return structured_content = { - "category" : category, - "content" : content, - "timestamp" : timestamp - } + "category" : category, + "content" : content, + "timestamp" : timestamp + } - log_file.write("{0}\n".format(dumps(structured_content))) + log_file.write("{0}\n".format(json.dumps(structured_content))) return (log_file, log) -no_chrome_driver = """ +NO_CHROME_DRIVER = """ You need to 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/likes.py b/deletefb/tools/likes.py index 6914145..abef381 100644 --- a/deletefb/tools/likes.py +++ b/deletefb/tools/likes.py @@ -2,11 +2,19 @@ from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC + from .common import SELENIUM_EXCEPTIONS, archiver + def load_likes(driver): """ Loads the page that lists all pages you like + + Args: + driver: seleniumrequests.Chrome Driver instance + + Returns: + None """ driver.get("https://www.facebook.com/pages/?category=liked") @@ -26,6 +34,12 @@ def load_likes(driver): def unlike_pages(driver): """ Unlike all pages + + Args: + driver: seleniumrequests.Chrome Driver instance + + Returns: + None """ like_log, archive_likes = archiver("likes") @@ -52,7 +66,7 @@ def unlike_pages(driver): print("{0} was unliked".format(page_name)) - except SELENIUM_EXCEPTIONS as e: + except SELENIUM_EXCEPTIONS: continue load_likes(driver) diff --git a/deletefb/tools/login.py b/deletefb/tools/login.py index 0a1ddd7..847649d 100644 --- a/deletefb/tools/login.py +++ b/deletefb/tools/login.py @@ -1,10 +1,12 @@ import time +import sys -from sys import stderr, exit +from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.chrome.options import Options from seleniumrequests import Chrome -from selenium.common.exceptions import NoSuchElementException -from .common import no_chrome_driver + +from .common import NO_CHROME_DRIVER + def login(user_email_address, user_password, @@ -14,9 +16,13 @@ def login(user_email_address, Attempts to log into Facebook Returns a driver object - user_email_address: str Your Email - user_password: str Your password - user_profile_url: str Your profile URL + Args: + user_email_address: str Your email + user_password: str Your password + user_profile_url: str Your profile URL + + Returns: + seleniumrequests.Chrome instance """ # The Chrome driver is required because Gecko was having issues @@ -35,9 +41,9 @@ def login(user_email_address, except Exception as e: # The user does not have chromedriver installed # Tell them to install it - stderr.write(str(e)) - stderr.write(no_chrome_driver) - exit(1) + sys.stderr.write(str(e)) + sys.stderr.write(NO_CHROME_DRIVER) + sys.exit(1) driver.implicitly_wait(10) @@ -45,7 +51,7 @@ def login(user_email_address, email = "email" password = "pass" - login = "loginbutton" + login_button = "loginbutton" approvals_code = "approvals_code" emailelement = driver.find_element_by_name(email) @@ -54,7 +60,7 @@ def login(user_email_address, emailelement.send_keys(user_email_address) passwordelement.send_keys(user_password) - loginelement = driver.find_element_by_id(login) + loginelement = driver.find_element_by_id(login_button) loginelement.click() # Defaults to no 2fa diff --git a/deletefb/tools/wall.py b/deletefb/tools/wall.py index 0264841..26da422 100644 --- a/deletefb/tools/wall.py +++ b/deletefb/tools/wall.py @@ -1,19 +1,26 @@ import time from selenium.webdriver.common.action_chains import ActionChains + from .common import SELENIUM_EXCEPTIONS, archiver # Used as a threshold to avoid running forever MAX_POSTS = 15000 + def delete_posts(driver, user_profile_url, year=None): """ Deletes or hides all posts from the wall + + Args: + driver: seleniumrequests.Chrome Driver instance + user_profile_url: str + year: optional int YYYY year """ - if not year is None: + if year is not None: user_profile_url = "{0}/timeline?year={1}".format(user_profile_url, year) driver.get(user_profile_url)