tootbot/tootbot.py

112 lines
4.0 KiB
Python
Raw Normal View History

2017-05-28 07:41:05 +00:00
import os.path
import sys
2019-04-03 15:44:07 +00:00
import re
import sqlite3
from datetime import datetime, timedelta
2017-05-28 07:41:05 +00:00
import feedparser
from mastodon import Mastodon
import requests
if len(sys.argv) < 4:
2019-04-03 15:46:13 +00:00
print("Usage: python3 tootbot.py twitter_account mastodon_login mastodon_passwd mastodon_instance") # noqa
2017-05-28 07:41:05 +00:00
sys.exit(1)
# sqlite db to store processed tweets (and corresponding toots ids)
sql = sqlite3.connect('tootbot.db')
db = sql.cursor()
2019-04-03 15:46:13 +00:00
db.execute('''CREATE TABLE IF NOT EXISTS tweets (tweet text, toot text,
twitter text, mastodon text, instance text)''')
2017-05-28 07:41:05 +00:00
2019-04-03 15:46:13 +00:00
if len(sys.argv) > 4:
2017-05-28 07:41:05 +00:00
instance = sys.argv[4]
else:
instance = 'amicale.net'
2019-04-03 15:46:13 +00:00
if len(sys.argv) > 5:
days = int(sys.argv[5])
else:
days = 1
2017-05-28 07:41:05 +00:00
twitter = sys.argv[1]
mastodon = sys.argv[2]
passwd = sys.argv[3]
mastodon_api = None
2017-05-28 07:41:05 +00:00
d = feedparser.parse('http://twitrss.me/twitter_user_to_rss/?user='+twitter)
for t in reversed(d.entries):
# check if this tweet has been processed
2019-04-03 15:46:13 +00:00
db.execute('SELECT * FROM tweets WHERE tweet = ? AND twitter = ? and mastodon = ? and instance = ?', (t.id, source, mastodon, instance)) # noqa
2017-05-28 07:41:05 +00:00
last = db.fetchone()
# process only unprocessed tweets less than 1 day old
if last is None and (datetime.now()-datetime(t.published_parsed.tm_year, t.published_parsed.tm_mon, t.published_parsed.tm_mday, t.published_parsed.tm_hour, t.published_parsed.tm_min, t.published_parsed.tm_sec) < timedelta(days=days)):
if mastodon_api is None:
# Create application if it does not exist
if not os.path.isfile(instance+'.secret'):
if Mastodon.create_app(
'tootbot',
api_base_url='https://'+instance,
2019-04-03 15:46:13 +00:00
to_file=instance+'.secret'
):
print('tootbot app created on instance '+instance)
else:
print('failed to create app on instance '+instance)
sys.exit(1)
try:
mastodon_api = Mastodon(
client_id=instance+'.secret',
api_base_url='https://'+instance
)
mastodon_api.log_in(
username=mastodon,
password=passwd,
scopes=['read', 'write'],
to_file=mastodon+".secret"
)
except:
print("ERROR: First Login Failed!")
sys.exit(1)
2017-05-28 07:41:05 +00:00
#h = BeautifulSoup(t.summary_detail.value, "html.parser")
c = t.title
2017-06-09 13:00:10 +00:00
if t.author.lower() != ('(@%s)' % twitter).lower():
c = ("RT https://twitter.com/%s\n" % t.author[2:-1]) + c
2017-05-28 07:41:05 +00:00
toot_media = []
# get the pictures...
for p in re.finditer(r"https://pbs.twimg.com/[^ \xa0\"]*", t.summary):
media = requests.get(p.group(0))
media_posted = mastodon_api.media_post(media.content, mime_type=media.headers.get('content-type'))
toot_media.append(media_posted['id'])
# replace t.co link by original URL
m = re.search(r"http[^ \xa0]*", c)
if m != None:
l = m.group(0)
r = requests.get(l, allow_redirects=False)
2019-04-03 15:46:13 +00:00
if r.status_code in {301, 302}:
c = c.replace(l, r.headers.get('Location'))
2017-05-28 07:41:05 +00:00
# remove pic.twitter.com links
m = re.search(r"pic.twitter.com[^ \xa0]*", c)
if m != None:
l = m.group(0)
2019-04-03 15:46:13 +00:00
c = c.replace(l, ' ')
2017-05-28 07:41:05 +00:00
# remove ellipsis
2017-06-08 15:48:05 +00:00
c = c.replace('\xa0',' ')
2017-05-28 07:41:05 +00:00
if toot_media is not None:
2019-04-03 15:46:13 +00:00
toot = mastodon_api.status_post(c, in_reply_to_id=None,
media_ids=toot_media,
sensitive=False,
visibility='public',
spoiler_text=None)
2017-05-28 07:41:05 +00:00
if "id" in toot:
db.execute("INSERT INTO tweets VALUES ( ? , ? , ? , ? , ? )",
(t.id, toot["id"], twitter, mastodon, instance))
sql.commit()