Implemented command line parsing

This commit is contained in:
JC Francois 2019-08-01 14:58:41 +02:00
parent 9b8b748b5a
commit 32f3eccc70

74
twoot.py Normal file → Executable file
View File

@ -19,6 +19,7 @@
''' '''
import sys import sys
import argparse
import os import os
import random import random
import requests import requests
@ -29,14 +30,6 @@ import re
from mastodon import Mastodon, MastodonError from mastodon import Mastodon, MastodonError
#TODO manage command line
TWIT_ACCOUNT = 'hackaday'
MAST_ACCOUNT = 'twoot@noirextreme.com'
MAST_PASSWORD = 'AcX/ZK5Ml6fRVDFi'
MAST_INSTANCE = 'mastodon.host'
MAX_AGE = 5 # in days
MIN_DELAY = 0 # in minutes
USER_AGENTS = [ USER_AGENTS = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/68.0', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/68.0',
@ -50,6 +43,7 @@ USER_AGENTS = [
#TODO log to file #TODO log to file
def cleanup_tweet_text(tt_iter): def cleanup_tweet_text(tt_iter):
''' '''
Receives an iterator over all the elements contained in the tweet-text container Receives an iterator over all the elements contained in the tweet-text container
@ -109,6 +103,27 @@ def cleanup_tweet_text(tt_iter):
return tweet_text return tweet_text
def main(argv):
# Build parser for command line arguments
parser = argparse.ArgumentParser(description='toot tweets.')
parser.add_argument('-t', metavar='<twitter account>', action='store', required=True)
parser.add_argument('-i', metavar='<mastodon instance>', action='store', required=True)
parser.add_argument('-m', metavar='<mastodon account>', action='store', required=True)
parser.add_argument('-p', metavar='<mastodon password>', action='store', required=True)
parser.add_argument('-a', metavar='<max age in days>', action='store', type=float, default=1)
parser.add_argument('-d', metavar='<min delay in mins>', action='store', type=float, default=0)
# Parse command line
args = vars(parser.parse_args())
twit_account = args['t']
mast_instance = args['i']
mast_account = args['m']
mast_password = args['p']
max_age = float(args['a'])
min_delay = float(args['d'])
# ********************************************************** # **********************************************************
# Load twitter page of user. Process all tweets and generate # Load twitter page of user. Process all tweets and generate
# list of dictionaries ready to be posted on Mastodon # list of dictionaries ready to be posted on Mastodon
@ -127,7 +142,7 @@ headers.update(
) )
# Download twitter page of user # Download twitter page of user
response = requests.get('https://twitter.com/' + TWIT_ACCOUNT, headers=headers) response = requests.get('https://twitter.com/' + twit_account, headers=headers)
# DEBUG: Save page to file # DEBUG: Save page to file
of = open('twitter.html', 'w') of = open('twitter.html', 'w')
@ -173,7 +188,7 @@ for result in results:
tweet_text = cleanup_tweet_text(tt_iter) tweet_text = cleanup_tweet_text(tt_iter)
# Check it the tweet is a retweet from somebody else # Check it the tweet is a retweet from somebody else
if author_account.lower() != TWIT_ACCOUNT.lower(): if author_account.lower() != twit_account.lower():
tweet_text = 'RT from ' + author + ' @' + author_account + '\n\n' + tweet_text tweet_text = 'RT from ' + author + ' @' + author_account + '\n\n' + tweet_text
# Add footer with link to original tweet # Add footer with link to original tweet
@ -210,7 +225,6 @@ for result in results:
for t in tweets: for t in tweets:
print(t) print(t)
# ********************************************************** # **********************************************************
# Iterate tweets. Check if the tweet has already been posted # Iterate tweets. Check if the tweet has already been posted
# on Mastodon. If not, post it and add it to database # on Mastodon. If not, post it and add it to database
@ -223,33 +237,33 @@ db.execute('''CREATE TABLE IF NOT EXISTS toots (twitter_account TEXT, mastodon_i
mastodon_account TEXT, tweet_id TEXT, toot_id TEXT)''') mastodon_account TEXT, tweet_id TEXT, toot_id TEXT)''')
# Create Mastodon application if it does not exist yet # Create Mastodon application if it does not exist yet
if not os.path.isfile(MAST_INSTANCE + '.secret'): if not os.path.isfile(mast_instance + '.secret'):
try: try:
Mastodon.create_app( Mastodon.create_app(
'twoot', 'twoot',
api_base_url='https://' + MAST_INSTANCE, api_base_url='https://' + mast_instance,
to_file=MAST_INSTANCE + '.secret' to_file=mast_instance + '.secret'
) )
except MastodonError as me: except MastodonError as me:
print('failed to create app on ' + MAST_INSTANCE) print('failed to create app on ' + mast_instance)
sys.exit(1) sys.exit(1)
# Log in to Mastodon instance # Log in to Mastodon instance
try: try:
mastodon = Mastodon( mastodon = Mastodon(
client_id=MAST_INSTANCE + '.secret', client_id=mast_instance + '.secret',
api_base_url='https://' + MAST_INSTANCE api_base_url='https://' + mast_instance
) )
mastodon.log_in( mastodon.log_in(
username=MAST_ACCOUNT, username=mast_account,
password=MAST_PASSWORD, password=mast_password,
to_file=MAST_ACCOUNT + ".secret" to_file=mast_account + ".secret"
) )
except MastodonError as me: except MastodonError as me:
print('ERROR: Login to ' + MAST_INSTANCE + ' Failed') print('ERROR: Login to ' + mast_instance + ' Failed')
print(me) print(me)
sys.exit(1) sys.exit(1)
@ -258,7 +272,7 @@ for tweet in reversed(tweets):
# Check in database if tweet has already been posted # Check in database if tweet has already been posted
db.execute('''SELECT * FROM toots WHERE twitter_account = ? AND mastodon_instance = ? AND db.execute('''SELECT * FROM toots WHERE twitter_account = ? AND mastodon_instance = ? AND
mastodon_account = ? AND tweet_id = ?''', mastodon_account = ? AND tweet_id = ?''',
(TWIT_ACCOUNT, MAST_INSTANCE, MAST_ACCOUNT, tweet['tweet_id'])) (twit_account, mast_instance, mast_account, tweet['tweet_id']))
tweet_in_db = db.fetchone() tweet_in_db = db.fetchone()
if tweet_in_db is not None: if tweet_in_db is not None:
@ -267,8 +281,8 @@ for tweet in reversed(tweets):
# Check that the tweet is not too young (might be deleted) or too old # Check that the tweet is not too young (might be deleted) or too old
age_in_hours = (time.time() - float(tweet['timestamp'])) / 3600.0 age_in_hours = (time.time() - float(tweet['timestamp'])) / 3600.0
min_delay_in_hours = float(MIN_DELAY) / 60.0 min_delay_in_hours = min_delay / 60.0
max_age_in_hours = float(MAX_AGE) * 24.0 max_age_in_hours = max_age * 24.0
if age_in_hours < min_delay_in_hours or age_in_hours > max_age_in_hours: if age_in_hours < min_delay_in_hours or age_in_hours > max_age_in_hours:
# Skip to next tweet # Skip to next tweet
@ -287,8 +301,8 @@ for tweet in reversed(tweets):
# Post toot # Post toot
try: try:
mastodon = Mastodon( mastodon = Mastodon(
access_token=MAST_ACCOUNT + '.secret', access_token=mast_account + '.secret',
api_base_url='https://' + MAST_INSTANCE api_base_url='https://' + mast_instance
) )
if len(media_ids) == 0: if len(media_ids) == 0:
@ -297,12 +311,16 @@ for tweet in reversed(tweets):
toot = mastodon.status_post(tweet['tweet_text'], media_ids=media_ids, visibility='public') toot = mastodon.status_post(tweet['tweet_text'], media_ids=media_ids, visibility='public')
except MastodonError as me: except MastodonError as me:
print('ERROR: posting ' + tweet['tweet_text'] + ' to ' + MAST_INSTANCE + ' Failed') print('ERROR: posting ' + tweet['tweet_text'] + ' to ' + mast_instance + ' Failed')
print(me) print(me)
sys.exit(1) sys.exit(1)
# Insert toot id into database # Insert toot id into database
if 'id' in toot: if 'id' in toot:
db.execute("INSERT INTO toots VALUES ( ? , ? , ? , ? , ? )", db.execute("INSERT INTO toots VALUES ( ? , ? , ? , ? , ? )",
(TWIT_ACCOUNT, MAST_INSTANCE, MAST_ACCOUNT, tweet['tweet_id'], toot['id'])) (twit_account, mast_instance, mast_account, tweet['tweet_id'], toot['id']))
sql.commit() sql.commit()
if __name__ == "__main__":
main(sys.argv)