From 40a9e5d0108097e2a87511b70966e958a7b3ee6c Mon Sep 17 00:00:00 2001 From: Lynne Date: Wed, 8 May 2019 06:29:32 +1000 Subject: [PATCH] it works! --- main.py | 44 ++++++++++++++++++++++++++++++++++++++------ requirements.txt | 3 ++- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index c1103ab..98742eb 100755 --- a/main.py +++ b/main.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 from mastodon import Mastodon import twitter +import requests -import sqlite3, json, re +import sqlite3, json, re, random cfg = { "cw":None, @@ -16,7 +17,7 @@ try: except: print("No config.json, using default configuration") -scopes = ["read:accounts", "write:statuses"] +scopes = ["read:accounts", "write:statuses", "write:media"] if "client" not in cfg: print("No application info -- registering application with {}".format(cfg['site'])) @@ -78,6 +79,10 @@ if "accounts" not in cfg: except: print("Invalid username.") + print("Saving account list. To choose a different set of accounts, delete the 'accounts' entry in config.json.") + cfg['accounts'] = accounts + + json.dump(cfg, open("config.json", "w+")) # connect to database @@ -85,19 +90,33 @@ db = sqlite3.connect("tip.db") db.text_factory=str c = db.cursor() -c.execute("CREATE TABLE IF NOT EXISTS `images` (post_id INT NOT NULL UNIQUE PRIMARY KEY, screen_name VARCHAR NOT NULL, image_url VARCHAR) WITHOUT ROWID") +c.execute("CREATE TABLE IF NOT EXISTS `images` (post_id INT NOT NULL UNIQUE PRIMARY KEY, screen_name VARCHAR NOT NULL, image_urls VARCHAR, count INT DEFAULT 0) WITHOUT ROWID") db.commit() -for acct in accounts: - last_tweet = c.execute("SELECT post_id FROM `images` WHERE user_id LIKE ? ORDER BY post_id DESC LIMIT 1", (acct,)).fetchone() +for acct in cfg['accounts']: + last_tweet = c.execute("SELECT post_id FROM `images` WHERE screen_name LIKE ? ORDER BY post_id DESC LIMIT 1", (acct,)).fetchone() if last_tweet != None: last_tweet = last_tweet[0] else: last_tweet = 0 # start from the first one print("Downloading tweets from account {}, starting from {}".format(acct, last_tweet)) - tl = api.GetUserTimeline(screen_name = acct, since_id = last_tweet, exclude_replies = True) + + while True: + tl = api.GetUserTimeline(screen_name = acct, since_id = last_tweet, exclude_replies = True, include_rts = False, count = 200, trim_user = True) + if len(tl) == 0: + # we've reached the end of this user's timeline + break + for tweet in tl: + media_urls = [] + if tweet.media != None: + for media in tweet.media: + media_urls.append(media.media_url) + c.execute("INSERT INTO `images` (screen_name, post_id, image_urls) VALUES (?, ?, ?)", (acct, tweet.id_str, ",".join(media_urls))) + last_tweet = c.execute("SELECT post_id FROM `images` WHERE screen_name LIKE ? ORDER BY post_id DESC LIMIT 1", (acct,)).fetchone()[0] + print(last_tweet) + db.commit() client = Mastodon( client_id=cfg['client']['id'], @@ -105,4 +124,17 @@ client = Mastodon( access_token=cfg['secret'], api_base_url=cfg['site']) +base_count = c.execute("SELECT MIN(count) FROM images").fetchone()[0] +# base_count gets the lowest post count from the table. +# for example, if image A and B have already been posted once, and image C has never been posted, it'll return 0. +# this lets us filter for images that haven't been posted yet in this "generation". + +chosen_tweet = c.execute("SELECT post_id, image_urls FROM images WHERE count = ? AND image_urls NOT LIKE '' ORDER BY RANDOM() LIMIT 1", (base_count,)).fetchone() +image = random.choice(chosen_tweet[1].split(",")) +filename = re.match(r".*\/(.*)", image).group(1) +# save image to disk +open(filename, 'wb').write(requests.get(image).content) +# post! +media = client.media_post(filename, description="Image downloaded from Twitter account {}".format(acct)) +client.status_post("Source: https://twitter.com/{}/status/{}".format(acct, chosen_tweet[0]), media_ids=media) diff --git a/requirements.txt b/requirements.txt index b7fda42..37ae3d3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ -Mastodon.py==1.3.1 +Mastodon.py==1.4.0 python-twitter==3.5 +requests==2.21.0