Browse Source

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.
pull/115/head
Alfred Sawaya 4 years ago
parent
commit
85d4e461b0
  1. 1
      .gitignore
  2. 30
      deletefb/deletefb.py
  3. 3
      deletefb/tools/config.py
  4. 50
      deletefb/tools/env_variables.py
  5. 12
      deletefb/tools/wall.py

1
.gitignore

@ -1,3 +1,4 @@
.envrc
__pycache__
venv
.mypy_cache

30
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()

3
deletefb/tools/config.py

@ -1,4 +1,5 @@
settings = {
"ARCHIVE" : True,
"MAX_POSTS" : 5000
"MAX_POSTS" : 5000,
"RETRY_THRESHOLD": 5
}

50
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)

12
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:

Loading…
Cancel
Save