Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions PostCleaner.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import json
import praw
import prawcore
import time
from datetime import datetime

from drive_upload import maybe_upload_logs

_RETRY_WAIT = (5, 15, 45)


def _with_retry(fn, label="operation"):
"""Call fn(), retrying up to 3 times on rate-limit errors."""
for attempt, wait in enumerate(_RETRY_WAIT, start=1):
try:
return fn()
except prawcore.exceptions.TooManyRequests as exc:
retry_after = getattr(exc, "retry_after", None) or wait
print(f" Rate limited on {label}. Waiting {retry_after}s (attempt {attempt}/3)…")
time.sleep(retry_after)
except praw.exceptions.APIException:
raise
return fn()


def get_reddit_credentials(credentials_file="Credentials.txt"):
"""
Expand Down Expand Up @@ -119,11 +136,11 @@ def delete_old_posts(reddit, username, days_old):
"source": "cli",
}) + "\n")
try:
submission.edit(".")
submission.delete()
_with_retry(lambda: submission.edit("."), "post edit")
_with_retry(submission.delete, "post delete")
posts_deleted += 1
print(f"Deleted post: {submission.title}")
except praw.exceptions.APIException as e:
except (praw.exceptions.APIException, prawcore.exceptions.TooManyRequests) as e:
print(f"Error removing post: {e}")

print(f"Deleted {posts_deleted} posts.")
Expand Down
35 changes: 26 additions & 9 deletions commentCleaner.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import json
import praw
import prawcore
import time
from datetime import datetime, timedelta

from drive_upload import maybe_upload_logs

_RETRY_WAIT = (5, 15, 45)


def _with_retry(fn, label="operation"):
"""Call fn(), retrying up to 3 times on rate-limit errors."""
for attempt, wait in enumerate(_RETRY_WAIT, start=1):
try:
return fn()
except prawcore.exceptions.TooManyRequests as exc:
retry_after = getattr(exc, "retry_after", None) or wait
print(f" Rate limited on {label}. Waiting {retry_after}s (attempt {attempt}/3)…")
time.sleep(retry_after)
except praw.exceptions.APIException:
raise
return fn()

def get_reddit_credentials(credentials_file="Credentials.txt"):
"""
Prompt the user to input Reddit client credentials.
Expand Down Expand Up @@ -115,10 +132,10 @@ def delete_old_comments(reddit, username, days_old, comments_deleted):
"source": "cli-mode-1",
}) + "\n")
try:
comment.edit(".")
comment.delete()
_with_retry(lambda: comment.edit("."), "comment edit")
_with_retry(comment.delete, "comment delete")
comments_deleted.append(comment)
except praw.exceptions.APIException as e:
except (praw.exceptions.APIException, prawcore.exceptions.TooManyRequests) as e:
print(f"Error deleting comment: {e}")


Expand Down Expand Up @@ -148,10 +165,10 @@ def remove_comments_with_negative_karma(reddit, username, comments_deleted):
"source": "cli-mode-2",
}) + "\n")
try:
comment.edit(".")
comment.delete()
_with_retry(lambda: comment.edit("."), "comment edit")
_with_retry(comment.delete, "comment delete")
comments_deleted.append(comment)
except praw.exceptions.APIException as e:
except (praw.exceptions.APIException, prawcore.exceptions.TooManyRequests) as e:
print(f"Error removing comment: {e}")


Expand Down Expand Up @@ -188,10 +205,10 @@ def remove_comments_with_one_karma_and_no_replies(reddit, username, comments_del
"source": "cli-mode-3",
}) + "\n")
try:
comment.edit(".")
comment.delete()
_with_retry(lambda: comment.edit("."), "comment edit")
_with_retry(comment.delete, "comment delete")
comments_deleted.append(comment)
except praw.exceptions.APIException as e:
except (praw.exceptions.APIException, prawcore.exceptions.TooManyRequests) as e:
print(f"Error removing comment: {e}")

def main():
Expand Down
26 changes: 22 additions & 4 deletions web/app.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import json
import os
import sys
import time
from datetime import datetime

import praw
import prawcore
from flask import Flask, jsonify, redirect, render_template, request, session, url_for

app = Flask(__name__)
Expand All @@ -19,6 +21,22 @@
DELETED_COMMENTS_FILE = os.path.join(BASE_DIR, "deleted_comments.txt")
DELETED_POSTS_FILE = os.path.join(BASE_DIR, "deleted_posts.txt")

_RETRY_WAIT = (5, 15, 45)


def _with_retry(fn, label="operation"):
"""Call fn(), retrying up to 3 times on rate-limit errors."""
for attempt, wait in enumerate(_RETRY_WAIT, start=1):
try:
return fn()
except prawcore.exceptions.TooManyRequests as exc:
retry_after = getattr(exc, "retry_after", None) or wait
print(f" Rate limited on {label}. Waiting {retry_after}s (attempt {attempt}/3)…")
time.sleep(retry_after)
except praw.exceptions.APIException:
raise
return fn()


def make_reddit():
return praw.Reddit(
Expand Down Expand Up @@ -138,8 +156,8 @@ def api_delete():
"body": comment.body,
"source": "web",
}) + "\n")
comment.edit(".")
comment.delete()
_with_retry(lambda: comment.edit("."), "comment edit")
_with_retry(comment.delete, "comment delete")
deleted_comments += 1
except Exception as e:
errors.append(f"Comment {cid}: {e}")
Expand All @@ -159,8 +177,8 @@ def api_delete():
"num_comments": submission.num_comments,
"source": "web",
}) + "\n")
submission.edit(".")
submission.delete()
_with_retry(lambda: submission.edit("."), "post edit")
_with_retry(submission.delete, "post delete")
deleted_posts += 1
except Exception as e:
errors.append(f"Post {pid}: {e}")
Expand Down
31 changes: 25 additions & 6 deletions weekly_cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,31 @@
import argparse
import json
import os
import time
from datetime import datetime, timezone

import praw
import prawcore

from drive_upload import maybe_upload_logs

_RETRY_WAIT = (5, 15, 45)


def _with_retry(fn, label="operation"):
"""Call fn(), retrying up to 3 times on rate-limit errors."""
for attempt, wait in enumerate(_RETRY_WAIT, start=1):
try:
return fn()
except prawcore.exceptions.TooManyRequests as exc:
retry_after = getattr(exc, "retry_after", None) or wait
print(f" Rate limited on {label}. Waiting {retry_after}s (attempt {attempt}/3)…")
time.sleep(retry_after)
except praw.exceptions.APIException:
raise
return fn()


AGE_THRESHOLD_DAYS = 14


Expand Down Expand Up @@ -105,11 +124,11 @@ def main(dry_run: bool = False):
"source": "ci",
}) + "\n")
try:
comment.edit(".")
comment.delete()
_with_retry(lambda: comment.edit("."), "comment edit")
_with_retry(comment.delete, "comment delete")
comments_deleted += 1
print(f" Deleted comment (score={comment.score}) in r/{comment.subreddit}")
except praw.exceptions.APIException as e:
except (praw.exceptions.APIException, prawcore.exceptions.TooManyRequests) as e:
print(f" Error deleting comment {comment.id}: {e}")

# ── Posts ─────────────────────────────────────────────────────────────
Expand All @@ -133,11 +152,11 @@ def main(dry_run: bool = False):
"source": "ci",
}) + "\n")
try:
submission.edit(".")
submission.delete()
_with_retry(lambda: submission.edit("."), "post edit")
_with_retry(submission.delete, "post delete")
posts_deleted += 1
print(f" Deleted post '{submission.title}' (score={submission.score}) in r/{submission.subreddit}")
except praw.exceptions.APIException as e:
except (praw.exceptions.APIException, prawcore.exceptions.TooManyRequests) as e:
print(f" Error deleting post {submission.id}: {e}")

if dry_run:
Expand Down