mastobot/mastobot.py

143 lines
4.7 KiB
Python

#!/usr/bin/python3
from mastodon import Mastodon
from dateutil.parser import parse
import tweepy, wget, os, time, json
settings_path = './settings.json'
with open(settings_path, 'r+') as fp:
settings = json.load(fp)
fp.close()
mastodon_instance = settings["mastodon"]["instance"]
clientcreds = settings["mastodon"]["clientcreds"]
transitions = settings["transitions"]
consumer_key = settings["twitter"]["consumer_key"]
consumer_secret = settings["twitter"]["consumer_secret"]
access_token_key = settings["twitter"]["access_token_key"]
access_token_secret = settings["twitter"]["access_token_secret"]
# Connect with Mastodon API
if not os.path.isfile(clientcreds):
Mastodon.create_app(
'MastoBot', api_base_url = mastodon_instance,
to_file = clientcreds
)
mastodon = Mastodon(client_id = clientcreds, api_base_url = mastodon_instance)
#Connect with Twitter API
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token_key, access_token_secret)
twitter_api = tweepy.API(auth)
# Looping the accounts
for account in transitions:
# Connect with Mastodon-Account
try:
usercreds = mastodon.log_in(
account['masto_username'].lower(),
account['masto_passwd']
)
except:
print(account['masto_username'].lower())
print("Login failed!")
continue
mastodon = Mastodon(
client_id = clientcreds,
access_token = usercreds,
api_base_url = mastodon_instance
)
# Looping the twitter statuses
statuses = twitter_api.user_timeline(screen_name = account['twitter_handle'], since_id = int(account['last_id']), count=25, tweet_mode="extended")
for status in reversed(statuses):
mastodon_text = ""
masto_media = []
# Does a extended_entities Array exist and does it contain info about media?
if "extended_entities" in status._json and "media" in status._json['extended_entities']:
media = status._json['extended_entities']['media']
# Post any media on Mastodon instance an save it to a list which will later be given to status.
for medium in media:
tmp_path = os.path.join("/tmp/", medium['id_str'] + '.jpg')
if medium['type'] == 'photo':
photo = wget.download(medium['media_url_https'], tmp_path)
# masto_photo = mastodon.media_post(tmp_path)
# masto_media.append(masto_photo)
# Is the post a retweet? Then give info about source to toot and get full text from there.
if 'retweeted_status' in status._json:
mastodon_text += "RT from " + status._json['retweeted_status']['user']['name'] + ": \n"
tweet_text = status._json['retweeted_status']['full_text']
tweet_origin = status._json['retweeted_status']['id_str']
# derefering twitter short urls to expanded
for url in status._json['retweeted_status']['entities']["urls"]:
tweet_text = tweet_text.replace(url["url"], url["expanded_url"])
else:
tweet_text = status.full_text
tweet_origin = status.id_str
# derefering twitter short urls to expanded
for url in status.entities["urls"]:
tweet_text = tweet_text.replace(url["url"], url["expanded_url"])
mastodon_text += tweet_text
# Add info about source and a related link to toot.
mastodon_text += "\n\nPosted " + parse(str(status.created_at)).strftime("%d. %B %Y - %H:%M on Twitter")
mastodon_text += "\nOrigin: https://twitter.com/" + account['twitter_handle'] + "/status/" + tweet_origin
# Make sure that 500 char limit of Mastodon-API doesn't break the script
if len(mastodon_text) > 500:
mastodon_text = mastodon_text[:489]
# Output text to stdout respect. post it to Mastodon.
print(mastodon_text)
try:
# mastodon.status_post(mastodon_text, None, masto_media, True, None,spoiler_text="Twitter RT")
continue
except:
print(account['twitter_handle'] + " couldn't toot to fediverse!\n")
continue
# mastodon.status_post(mastodon_text, None, masto_media, True)
time.sleep(2)
# If there are new statuses for account update the "last_id" to the newest one.
if statuses:
print(account['twitter_handle'] + " : " + str(status.id))
#account['last_id'] = str(status.id)
# Write updated settings to json-file
with open(settings_path, 'w') as fp:
json.dump(settings,fp)
fp.close()