diff --git a/README.md b/README.md index f9faaf4..4025a19 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Twitter timeline cleaner -Clean your Twitter timeline +## Clean your Twitter timeline +## Prerequisites Before running, remember to set these environment variables: ``` @@ -13,6 +14,21 @@ export TWITTER_NAME='@your_twitter_name' and follow the instructions to claim a [Twitter developers account](https://developer.twitter.com/en/apply) and [to create an app](https://developer.twitter.com/en/apps/create), needed to fetch your Twitter timeline's tokens and keys. +## Usage + +``` +usage: twitter-timeline-cleaner.py [-h] --until UNTIL_DATE [--dry-run] [--save] [--limit LIMIT] + +Maintain clean your Twitter timeline + +optional arguments: + -h, --help show this help message and exit + --until UNTIL_DATE delete tweets until this date (YYYY-MM-DD) + --dry-run simulate (don't delete anything) + --save save deleted tweets in JSON + --limit LIMIT define how many tweets to delete (default: all) +``` + Article in italian talking about this project: [Ripulire la propria Twitter timeline](https://www.zerozone.it/tecnologia-privacy-e-sicurezza/ripulire-la-propria-twitter-timeline/19195) Work inspired by [delete-tweets](https://github.com/koenrh/delete-tweets) by Koen Rouwhorst diff --git a/twitter-timeline-cleaner.py b/twitter-timeline-cleaner.py index 4518078..7f07ab8 100644 --- a/twitter-timeline-cleaner.py +++ b/twitter-timeline-cleaner.py @@ -1,11 +1,18 @@ #!/usr/bin/env python3 # -### Twitter timeline cleaner ### +# Twitter timeline cleaner +# v0.0.2 # # by Michele Pinassi # -# https://www.zerozone.it/tecnologia-privacy-e-sicurezza/ripulire-la-propria-twitter-timeline/19195 +# Released under GPL v3 # +# More @ https://www.zerozone.it/tecnologia-privacy-e-sicurezza/ripulire-la-propria-twitter-timeline/19195 +# +# v0.0.2 - 25.07.2021 +# - added "save" and "limit" options +# + from __future__ import print_function import os @@ -13,7 +20,7 @@ import json import sys import argparse -from datetime import datetime +from datetime import datetime, date from dateutil import parser import twitter @@ -40,8 +47,10 @@ def get_tweets(api=None, screen_name=None): def main(): argparser = argparse.ArgumentParser(description="Maintain clean your Twitter timeline") - argparser.add_argument("--until", dest="until_date", required=True, help="Delete tweets until this date (YYYY-MM-DD)") - argparser.add_argument("--dry-run", dest="dry_run", action="store_true", default=False) + argparser.add_argument("--until", dest="until_date", required=True, help="delete tweets until this date (YYYY-MM-DD)") + argparser.add_argument("--dry-run", dest="dry_run", action="store_true", default=False help="simulate (don't delete anything)") + argparser.add_argument("--save", dest="save", action="store_true", default=False, help="Save deleted tweets in JSON") + argparser.add_argument("--limit", dest="limit", default=False, help="define how many tweets to delete (default: all)") args = argparser.parse_args() @@ -53,29 +62,62 @@ def main(): sys.stderr.write("Twitter API credentials not set.\n") exit(1) + print("[#] Connection to Twitter API...") + api = twitter.Api(consumer_key=os.environ["TWITTER_CONSUMER_KEY"],consumer_secret=os.environ["TWITTER_CONSUMER_SECRET"],access_token_key=os.environ["TWITTER_ACCESS_TOKEN"],access_token_secret=os.environ["TWITTER_ACCESS_TOKEN_SECRET"],sleep_on_rate_limit=True) + try: + api.VerifyCredentials() + except twitter.TwitterError as err: + print("[!] API error: %s. Please verify credentials and try again!"%err.message) + exit(1) + until_date = datetime.min if args.until_date is None else parser.parse(args.until_date, ignoretz=True) - timeline = get_tweets(api=api, screen_name=os.environ["TWITTER_NAME"]) + if args.save: + now = datetime.now() + filename='tweets_%s.json'%(now.strftime('%Y%b%d')) + json_file = open(filename, 'w') + print("[#] Saving deleted tweets to %s"%filename) + + print("[#] Fetch tweets for %s..."%os.environ["TWITTER_NAME"]) + + try: + timeline = get_tweets(api=api, screen_name=os.environ["TWITTER_NAME"]) + except twitter.TwitterError as err: + print("Exception: %s\n" % err.message) + exit(1) + + tweet_count=0 for tweet in timeline: - - print(tweet._json) - tweet_date = parser.parse(tweet._json["created_at"], ignoretz=True) tweet_id = tweet._json['id'] if tweet_date >= until_date: continue + tweet_count+=1 + if args.limit and tweet_count > args.limit: + break + + print(tweet._json) + + if args.save: + print("[#] Save tweet ID %d to file..."%tweet_id) + json.dump(tweet._json,json_file) + try: - print("delete tweet %s" % tweet_id) + print("[!] Delete tweet %s" % tweet_id) if not args.dry_run: api.DestroyStatus(tweet_id) except twitter.TwitterError as err: print("Exception: %s\n" % err.message) + print("[#] DONE! Deleted %d tweet(s) from yout timeline"%tweet_count) + + if args.save: + json_file.close() if __name__ == "__main__": main()