import time import os from datetime import datetime, timedelta import humanfriendly from mastodon import Mastodon import psycopg2 def get_uptime(): try: conn = None conn = psycopg2.connect(database=fediverse_db, user=fediverse_db_user, password="", host="/var/run/postgresql", port="5432") cur = conn.cursor() cur.execute("select count(server) from fediverse where alive") row = cur.fetchone() alive_servers = row[0] cur.execute("select MAX(last_checked_at - first_checked_at) from fediverse") row = cur.fetchone() max_uptime = row[0] cur.execute("select count(server) from fediverse where last_checked_at-first_checked_at=(%s)", (max_uptime,)) row = cur.fetchone() if row is not None: best_servers = row[0] cur.execute("select software, count(*) as servers from fediverse where last_checked_at-first_checked_at=(%s) group by software order by servers desc", (max_uptime,)) rows = cur.fetchall() software_lst = [] servers_lst = [] for row in rows: software_lst.append(row[0]) servers_lst.append(row[1]) cur.close() return (alive_servers, max_uptime, best_servers, software_lst, servers_lst) except (Exception, psycopg2.DatabaseError) as error: print(error) finally: if conn is not None: conn.close() def get_percentage(uptime_servers, software): try: conn = None conn = psycopg2.connect(database=fediverse_db, user=fediverse_db_user, password="", host="/var/run/postgresql", port="5432") cur = conn.cursor() cur.execute("select count(server) from fediverse where alive and software=(%s)", (software,)) row = cur.fetchone() if row is not None: soft_total_servers = row[0] cur.close() soft_uptime_percent = round((uptime_servers * 100) / soft_total_servers, 1) return (soft_uptime_percent) except (Exception, psycopg2.DatabaseError) as error: print(error) finally: if conn is not None: conn.close() def mastodon(): # Load secrets from secrets file secrets_filepath = "secrets/uptime_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" fediverse_db = get_parameter("fediverse_db", config_filepath) fediverse_db_user = get_parameter("fediverse_db_user", config_filepath) return (fediverse_db, fediverse_db_user) # 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__': mastodon, mastodon_hostname = mastodon() fediverse_db, fediverse_db_user = db_config() alive_servers, max_uptime, best_servers, software_lst, servers_lst = get_uptime() toot_text = '\nAlive servers: ' + str(alive_servers) toot_text += '\n\n' toot_text += f"Best #fediverse's server uptime:\n{humanfriendly.format_timespan(max_uptime)}" toot_text += '\n' toot_text += f'\nBest uptime servers:\n{str(best_servers)} ({str(round((best_servers*100)/alive_servers,2))}%)' toot_text += '\n\n' toot_text += 'Best uptime softwares & servers:\n' i = 0 while i < len(software_lst): soft_percent = get_percentage(servers_lst[i], software_lst[i]) toot_text += ':' + str(software_lst[i]) + ': ' + str(servers_lst[i]) + ' (' + str(soft_percent) + '%)\n' if len(toot_text) > 470: break i +=1 print("Tooting...") print(toot_text) mastodon.status_post(toot_text, in_reply_to_id=None)