This commit is contained in:
michelep 2021-07-25 23:26:33 +02:00
parent 92576b5a31
commit 61cf145686
2 changed files with 69 additions and 11 deletions

View File

@ -1,6 +1,7 @@
# Twitter timeline cleaner # Twitter timeline cleaner
Clean your Twitter timeline ## Clean your Twitter timeline
## Prerequisites
Before running, remember to set these environment variables: 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. 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) 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 Work inspired by [delete-tweets](https://github.com/koenrh/delete-tweets) by Koen Rouwhorst

View File

@ -1,11 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# #
### Twitter timeline cleaner ### # Twitter timeline cleaner
# v0.0.2
# #
# by Michele <o-zone@zerozone.it> Pinassi # by Michele <o-zone@zerozone.it> 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 from __future__ import print_function
import os import os
@ -13,7 +20,7 @@ import json
import sys import sys
import argparse import argparse
from datetime import datetime from datetime import datetime, date
from dateutil import parser from dateutil import parser
import twitter import twitter
@ -40,8 +47,10 @@ def get_tweets(api=None, screen_name=None):
def main(): def main():
argparser = argparse.ArgumentParser(description="Maintain clean your Twitter timeline") 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("--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("--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() args = argparser.parse_args()
@ -53,29 +62,62 @@ def main():
sys.stderr.write("Twitter API credentials not set.\n") sys.stderr.write("Twitter API credentials not set.\n")
exit(1) 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) 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) 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: for tweet in timeline:
print(tweet._json)
tweet_date = parser.parse(tweet._json["created_at"], ignoretz=True) tweet_date = parser.parse(tweet._json["created_at"], ignoretz=True)
tweet_id = tweet._json['id'] tweet_id = tweet._json['id']
if tweet_date >= until_date: if tweet_date >= until_date:
continue 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: try:
print("delete tweet %s" % tweet_id) print("[!] Delete tweet %s" % tweet_id)
if not args.dry_run: if not args.dry_run:
api.DestroyStatus(tweet_id) api.DestroyStatus(tweet_id)
except twitter.TwitterError as err: except twitter.TwitterError as err:
print("Exception: %s\n" % err.message) 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__": if __name__ == "__main__":
main() main()