From 3e9a95972aa49eb434ac57619c47c72eff71aa2f Mon Sep 17 00:00:00 2001 From: Alfred Sawaya Date: Thu, 13 Feb 2020 15:35:37 +0100 Subject: [PATCH 1/2] clean deletefb.log --- deletefb/deletefb.log | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 deletefb/deletefb.log diff --git a/deletefb/deletefb.log b/deletefb/deletefb.log deleted file mode 100644 index e69de29..0000000 -- 2.30.2 From 85d4e461b0bc45489a549ae0bfd7157c286d12f5 Mon Sep 17 00:00:00 2001 From: Alfred Sawaya Date: Thu, 13 Feb 2020 15:36:19 +0100 Subject: [PATCH 2/2] Set a maximum of refreshes when wall is empty The previous behaviour was to try to delete 5000 posts, even if the wall is empty. The drawback was that if you want to delete only 10 posts, then you would wait 5000*5 secondes (~7 hours) before the end of the script. Now, you can set a number of tries before quitting. If the delete button is not found consecutively during this number of times, then we break the loop. I also added an environment variable parser like argparse to ease the future use of other env variables. --- .gitignore | 1 + deletefb/deletefb.py | 30 ++++++++++++++++++-- deletefb/tools/config.py | 3 +- deletefb/tools/env_variables.py | 50 +++++++++++++++++++++++++++++++++ deletefb/tools/wall.py | 12 +++++++- 5 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 deletefb/tools/env_variables.py diff --git a/.gitignore b/.gitignore index c45468f..49018cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .envrc __pycache__ venv +.mypy_cache diff --git a/deletefb/deletefb.py b/deletefb/deletefb.py index 4d8c5a9..68a1127 100755 --- a/deletefb/deletefb.py +++ b/deletefb/deletefb.py @@ -6,6 +6,7 @@ from .tools.login import login from .tools.wall import delete_posts from .tools.conversations import traverse_conversations from .tools.comments import delete_comments +from .tools.env_variables import EnvParser import argparse import getpass @@ -13,8 +14,18 @@ import sys LOG = logger("deletefb") + def run_delete(): parser = argparse.ArgumentParser() + env_parser = EnvParser() + + parser.add_argument( + "--help-env", + action="store_true", + dest="help_env", + default=False, + help="Print help about environment variables" + ) parser.add_argument( "-M", @@ -30,7 +41,7 @@ def run_delete(): parser.add_argument( "-E", "--email", - required=True, + required='--help-env' not in sys.argv, dest="email", type=str, help="Your email address associated with the account" @@ -48,7 +59,7 @@ def run_delete(): parser.add_argument( "-U", "--profile-url", - required=True, + required='--help-env' not in sys.argv, dest="profile_url", type=str, help="The link to your Facebook profile, e.g. https://www.facebook.com/your.name" @@ -99,9 +110,23 @@ def run_delete(): help="Optional path to the Google Chrome (or Chromium) binary" ) + env_parser.add_argument( + "DELETEFB_RETRY_THRESHOLD", + default=5, + dest="retry_threshold", + type=int, + help="Number of refreshes to ensure your wall is empty before quitting" + ) + args = parser.parse_args() + env = env_parser.parse_args() + + if args.help_env: + env_parser.print_help() + sys.exit(0) settings["ARCHIVE"] = not args.archive_off + settings["RETRY_THRESHOLD"] = env.retry_threshold if args.year and args.mode not in ("wall", "conversations"): parser.error("The --year option is not supported in this mode") @@ -133,5 +158,6 @@ def run_delete(): print("Please enter a valid mode") sys.exit(1) + if __name__ == "__main__": run_delete() diff --git a/deletefb/tools/config.py b/deletefb/tools/config.py index 078efca..16fd87a 100644 --- a/deletefb/tools/config.py +++ b/deletefb/tools/config.py @@ -1,4 +1,5 @@ settings = { "ARCHIVE" : True, - "MAX_POSTS" : 5000 + "MAX_POSTS" : 5000, + "RETRY_THRESHOLD": 5 } diff --git a/deletefb/tools/env_variables.py b/deletefb/tools/env_variables.py new file mode 100644 index 0000000..d02ac3e --- /dev/null +++ b/deletefb/tools/env_variables.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +import sys +import os +import re +import typing as ty + +from types import SimpleNamespace + + +class EnvVar: + def __init__(self, + env_key: str, + dest: ty.Optional[str] = None, + type: ty.Type = str, + default: ty.Optional[str] = None, + help: ty.Optional[str] = None): + + assert re.match('^[a-zA-Z_]+[a-zA-Z0-9_]*$', env_key), "Bad env key {0}".format(env_key) + self.key = env_key + self.dest = dest or env_key.lower() + self.type = type + self.help = help + self.default = default + + +class EnvParser: + def __init__(self): + self.env_vars = set() + + def add_argument(self, *args, **kwargs): + self.env_vars.add(EnvVar(*args, **kwargs)) + + def print_help(self): + print("environment variables:") + for v in self.env_vars: + print(" {0}=<{1}>\t{2}".format(v.key, v.type.__name__, v.help or '')) + + def parse_args(self): + args = {} + for v in self.env_vars: + try: + args[v.dest] = v.type(os.environ.get(v.key, v.default)) + except ValueError: + print("{0}: error: environment variable {1} should be of type {2}".format( + sys.argv[0].split('/')[-1], + v.key, + v.type.__name__)) + sys.exit(1) + return SimpleNamespace(**args) diff --git a/deletefb/tools/wall.py b/deletefb/tools/wall.py index fb8ff69..3ed93d4 100644 --- a/deletefb/tools/wall.py +++ b/deletefb/tools/wall.py @@ -26,7 +26,11 @@ def delete_posts(driver, driver.get(user_profile_url) + retry_threshold = 0 for _ in range(MAX_POSTS): + if retry_threshold >= settings["RETRY_THRESHOLD"]: + break + post_button_sel = "_4xev" post_content_sel = "userContent" @@ -36,6 +40,9 @@ def delete_posts(driver, with archiver("wall") as archive_wall_post: while True: + if retry_threshold >= settings["RETRY_THRESHOLD"]: + break + try: timeline_element = driver.find_element_by_class_name(post_button_sel) @@ -67,15 +74,18 @@ def delete_posts(driver, continue if not delete_button: + retry_threshold += 1 print("Could not find anything to delete") break + else: + retry_threshold = 0 click_button(driver, delete_button) confirmation_button = driver.find_element_by_class_name("layerConfirm") click_button(driver, confirmation_button) - except SELENIUM_EXCEPTIONS as e: + retry_threshold += 1 print(e) continue else: -- 2.30.2