You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

468 lines
14 KiB
Python

import datetime
from mastodon import Mastodon
import time
import os
import json
import sys
import os.path
import operator
import psycopg2
import pdb
def mastodon():
# Load secrets from secrets file
secrets_filepath = "secrets/secrets.txt"
uc_client_id = get_parameter("uc_client_id", secrets_filepath)
uc_client_secret = get_parameter("uc_client_secret", secrets_filepath)
uc_access_token = get_parameter("uc_access_token", secrets_filepath)
# Load configuration from config file
config_filepath = "config/config.txt"
mastodon_hostname = get_parameter("mastodon_hostname", config_filepath)
# Initialise Mastodon API
mastodon = Mastodon(
client_id=uc_client_id,
client_secret=uc_client_secret,
access_token=uc_access_token,
api_base_url='https://' + mastodon_hostname,
)
# Initialise access headers
headers = {'Authorization': 'Bearer %s'%uc_access_token}
return (mastodon, mastodon_hostname)
def db_config():
# Load db configuration from config file
config_filepath = "config/db_config.txt"
mastodon_db = get_parameter("mastodon_db", config_filepath)
mastodon_db_user = get_parameter("mastodon_db_user", config_filepath)
welcome_db = get_parameter("welcome_db", config_filepath)
welcome_db_user = get_parameter("welcome_db_user", config_filepath)
return (mastodon_db, mastodon_db_user, welcome_db, welcome_db_user)
def get_locale( parameter, welcome_lang):
if welcome_lang not in ['ca','es','en']:
print("lang must be 'ca', 'es' or 'en'")
sys.exit(0)
language_filepath = f"app/locales/{welcome_lang}.txt"
if not os.path.isfile(language_filepath):
print("File %s not found, exiting."%language_filepath)
sys.exit(0)
with open( language_filepath ) as f:
for line in f:
if line.startswith( parameter ):
return line.replace(parameter + ":", "").strip()
print(language_filepath + " Missing parameter %s "%parameter)
sys.exit(0)
def usage():
print('usage: python ' + sys.argv[0] + ' --ca (or --es or --en)')
# Returns the parameter from the specified file
def get_parameter( parameter, file_path ):
# Check if secrets file exists
if not os.path.isfile(file_path):
print("File %s not found, exiting."%file_path)
sys.exit(0)
# Find parameter in file
with open( file_path ) as f:
for line in f:
if line.startswith( parameter ):
return line.replace(parameter + ":", "").strip()
# Cannot find parameter, exit
print(file_path + " Missing parameter %s "%parameter)
sys.exit(0)
###############################################################################
# main
if __name__ == '__main__':
# usage modes
if len(sys.argv) == 1:
usage()
elif len(sys.argv) >= 2:
welcome_lang = ''
if sys.argv[1] == '--ca':
welcome_lang = 'ca'
if sys.argv[1] == '--es':
welcome_lang = 'es'
elif sys.argv[1] == '--en':
welcome_lang = 'en'
if not welcome_lang in ['ca', 'es', 'en']:
print("\nOnly 'ca', 'es' and 'en' languages are supported.\n")
sys.exit(0)
mastodon, mastodon_hostname = mastodon()
mastodon_db, mastodon_db_user, welcome_db, welcome_db_user = db_config()
###############################################################################
# current registered users
###############################################################################
try:
conn = None
conn = psycopg2.connect(database = mastodon_db, user = mastodon_db_user, password = "", host = "/var/run/postgresql", port = "5432")
cur = conn.cursor()
cur.execute("SELECT count(*) FROM users WHERE disabled='f' and approved='t'")
row = cur.fetchone()
if row != None:
current_id = row[0]
else:
current_id = 0
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print (error)
finally:
if conn is not None:
conn.close()
###############################################################################
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
users_before = current_id
users_hour = 0
conn = None
try:
conn = psycopg2.connect(database = welcome_db, user = welcome_db_user, password = "", host = "/var/run/postgresql", port = "5432")
cur = conn.cursor()
cur.execute("SELECT DISTINCT ON (datetime) users FROM welcome WHERE datetime > current_timestamp - INTERVAL '70 minutes' ORDER BY datetime asc LIMIT 1")
row = cur.fetchone()
users_before = row[0]
cur.close()
users_hour = current_id - users_before
except (Exception, psycopg2.DatabaseError) as error:
print (error)
finally:
if conn is not None:
conn.close()
current_users_str = get_locale("current_users_str", welcome_lang)
users_before_str = get_locale("users_before_str", welcome_lang)
users_hour_str = get_locale("users_hour_str", welcome_lang)
print("-----------------")
print(current_users_str + ': ' + str(current_id))
print(users_before_str + ': ' + str(users_before))
print(users_hour_str + ': ' + str(users_hour))
insert_sql = """INSERT INTO welcome(datetime, users, users_hour)
VALUES(%s,%s,%s) RETURNING datetime;"""
conn = None
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
conn = psycopg2.connect(database = welcome_db, user = welcome_db_user, password = "", host = "/var/run/postgresql", port = "5432")
cur = conn.cursor()
cur.execute(insert_sql, (now, current_id, users_hour))
datetime = cur.fetchone()[0]
conn.commit()
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
###############################################################################
# WORK OUT THE TOOT TEXT
###############################################################################
# Calculate difference in times
hourly_change_string = ""
daily_change_string = ""
weekly_change_string = ""
users_hourly_change_string = ""
try:
conn = None
conn = psycopg2.connect(database = welcome_db, user = welcome_db_user, password = "", host = "/var/run/postgresql", port = "5432")
cur = conn.cursor()
cur.execute("SELECT DISTINCT ON (datetime) users, datetime FROM welcome WHERE datetime > current_timestamp - INTERVAL '62 minutes' ORDER BY datetime asc LIMIT 1")
row = cur.fetchone()
if row[0] == None:
users_last_hour = 0
else:
users_last_hour = row[0]
cur.execute("SELECT DISTINCT ON (datetime) users,datetime FROM welcome WHERE datetime > current_timestamp - INTERVAL '1 day' ORDER BY datetime asc LIMIT 1")
row = cur.fetchone()
if row[0] == None:
users_last_day = 0
else:
users_last_day = row[0]
cur.execute("SELECT DISTINCT ON (datetime) users,datetime FROM welcome WHERE datetime > current_timestamp - INTERVAL '7 days' ORDER BY datetime asc LIMIT 1")
row = cur.fetchone()
if row[0] == None:
users_last_week = 0
else:
users_last_week = row[0]
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print (error)
finally:
if conn is not None:
conn.close()
#################################################################################
welcome_users = []
if time.localtime().tm_isdst == 0:
interval_time = '60 minutes'
elif time.localtime().tm_isdst == 1:
interval_time = '120 minutes'
conn = None
try:
conn = psycopg2.connect(database = mastodon_db, user = mastodon_db_user, password = "", host = "/var/run/postgresql", port = "5432")
cur = conn.cursor()
cur.execute("select username, domain from accounts where (created_at + interval '" + interval_time + "' > (now() - interval '1 hour')) and domain is null and suspended_at is null and id in (select account_id from users where approved and not disabled)")
rows = cur.fetchall()
for row in rows:
if row[1] == None:
welcome_users.append(row[0])
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
i = 0
new_users_string = ""
while i < len(welcome_users):
new_users_string = new_users_string+"@"+welcome_users[i]
i += 1
if i < len(welcome_users):
new_users_string = new_users_string+", "
#########################################################################################################
hour_inc = current_id - users_last_hour
day_inc = current_id - users_last_day
week_inc = current_id - users_last_week
new_users_last_hour_str = get_locale("new_users_last_hour_str", welcome_lang)
new_users_last_day_str = get_locale("new_users_last_day_str", welcome_lang)
new_users_last_week_str = get_locale("new_users_last_week_str", welcome_lang)
print("------------------------")
print(new_users_last_hour_str + ': ' + str(hour_inc))
print(new_users_last_day_str + ': ' + str(day_inc))
print(new_users_last_week_str + ': ' + str(week_inc))
###################################################################################
# Hourly change
if hour_inc != 0:
users_hourly_change = current_id - users_last_hour
hourly_users_evolution_str = get_locale("hourly_users_evolution_str", welcome_lang)
in_the_last_hour_str = get_locale("in_the_last_hour_str", welcome_lang)
print(hourly_users_evolution_str + ': %s'%users_hourly_change)
if users_hourly_change > 0:
hourly_change_string = "+" + format(users_hourly_change, ",d") + in_the_last_hour_str + "\n"
# Daily change
if day_inc != 0:
daily_change = current_id - users_last_day
daily_users_evolution_str = get_locale("daily_users_evolution_str", welcome_lang)
in_the_last_day_str = get_locale("in_the_last_day_str", welcome_lang)
print(daily_users_evolution_str + ': %s'%daily_change)
if daily_change > 0:
daily_change_string = "+" + format(daily_change, ",d") + in_the_last_day_str + "\n"
# Weekly change
if week_inc != 0:
weekly_change = current_id - users_last_week
weekly_users_evolution_str = get_locale("weekly_users_evolution_str", welcome_lang)
in_the_last_week_str = get_locale("in_the_last_week_str", welcome_lang)
print(weekly_users_evolution_str + ': %s'%weekly_change)
if weekly_change > 0:
weekly_change_string = "+" + format(weekly_change, ",d") + in_the_last_week_str + "\n"
elif users_hourly_change < 0:
hourly_change_string = format(users_hourly_change, ",d") + in_the_last_hour_str + "\n"
# Daily change
if day_inc != 0:
daily_change = current_id - users_last_day
daily_evolution_str = get_locale("daily_evolution_str", welcome_lang)
print(daily_evolution_str + ': %s'%daily_change)
if daily_change < 0:
daily_change_string = format(daily_change, ",d") + in_the_last_day_str + "\n"
# Weekly change
if week_inc != 0:
weekly_change = current_id - users_last_week
weekly_evolution_str = get_locale("weekly_evolution_str", welcome_lang)
print(weekly_evolution_str + ': %s'%weekly_change)
if weekly_change < 0:
weekly_change_string = format(weekly_change, ",d") + in_the_last_week_str + "\n"
###############################################################################
# TOOT IT!
###############################################################################
if len(welcome_users) > 0:
welcomes_str = get_locale("welcomes_str", welcome_lang)
we_have_str = get_locale("we_have_str", welcome_lang)
users_str = get_locale("users_str", welcome_lang)
toot_text = "\n"
toot_text += mastodon_hostname + ' ' + welcomes_str + ':\n\n'
toot_text += new_users_string + "\n"
toot_text += "\n"
toot_text += "\n\n" + we_have_str + ' ' + str(current_id) + ' ' + users_str + "\n\n"
toot_text += hourly_change_string
toot_text += daily_change_string
toot_text += weekly_change_string
toot_text += "\n"
print("Tooting...")
print(toot_text)
if len(toot_text) < 500:
mastodon.status_post(toot_text, in_reply_to_id=None, )
else:
toot_text1, toot_text2 = toot_text[:int(len(toot_text)/2)], toot_text[int(len(toot_text)/2):]
toot_id = mastodon.status_post(toot_text1, in_reply_to_id=None,)
mastodon.status_post(toot_text2, in_reply_to_id=toot_id,)
print(toot_text1)
print(toot_text2)
print("Done!")