From c5ba1ddab89b37fa467d4147a58cad6a79329f1c Mon Sep 17 00:00:00 2001 From: spla Date: Sat, 21 Aug 2021 11:15:23 +0200 Subject: [PATCH 01/11] Added Best Fediverse's servers Uptime Publishing Bot --- uptime.py | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 uptime.py diff --git a/uptime.py b/uptime.py new file mode 100644 index 0000000..4cba8a8 --- /dev/null +++ b/uptime.py @@ -0,0 +1,149 @@ +import time +import os +from datetime import datetime, timedelta +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() + + if row[0] != timedelta(0): + + 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 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 += "Best #fediverse's server uptime:\n" + str(max_uptime) + toot_text += '\n' + toot_text += 'Servers with best uptime: ' + str(best_servers) + toot_text += '\n\n' + toot_text += 'software & servers with best uptime:' + '\n' + i = 0 + while i < len(software_lst): + + toot_text += ':' + str(software_lst[i]) + ': ' + str(servers_lst[i]) + '\n' + + if len(toot_text) > 480: + break + i +=1 + + print("Tooting...") + print(toot_text) + + mastodon.status_post(toot_text, in_reply_to_id=None) From 25cf9611a664ecdfa806f4f344fd45f8ef981169 Mon Sep 17 00:00:00 2001 From: spla Date: Sat, 21 Aug 2021 11:19:32 +0200 Subject: [PATCH 02/11] Updated README.md - Best Fediverse's servers Uptime Publishing Bot --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 29416a0..a9fe9c5 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,11 @@ Within Python Virtual Environment: | writefreely | api/nodeinfo | ['software']['name'] | | zap | nodeinfo/2.0.json | ['software']['name'] | -5. Use your favourite scheduling method to set `python fediverse.py` to run twice daily, `python fetchservers.py` one time daily and `python getworld.py` to run monthly. +7. Run `python uptime_setup.py` to get your Uptime bot's access token of your Mastodon or Pleroma server existing account. It will be saved to 'secrets/uptime_secrets.txt' for further use. -18.2.21 - New feature! Added [Lemmy project](https://join.lemmy.ml) -12.5.21 - New feature! Added Wordpress support. The code can now detect Wordpress instances with ActivityPub enabled plugin. -12.5.21 - New feature! New shinny creation of servers and users graphs. +8. Use your favourite scheduling method to set `python fediverse.py` to run twice daily, `python fetchservers.py` one time daily, `python getworld.py` to run monthly and `python uptime.py` (choose your desired frequency) if you want to publish best fediverse's servers uptime. + +18.2.2021 - New feature! Added [Lemmy project](https://join.lemmy.ml) +12.5.2021 - New feature! Added Wordpress support. The code can now detect Wordpress instances with ActivityPub enabled plugin. +12.5.2021 - New feature! New shinny creation of servers and users graphs. +21.8.2021 - New feature! Added Best Fediverse's servers Uptime publishing bot. From cf6cc29a15c4805eb7e96c9f0bf2f3af535867aa Mon Sep 17 00:00:00 2001 From: spla Date: Sat, 21 Aug 2021 11:22:59 +0200 Subject: [PATCH 03/11] Added tokens setup of Best Fediverse Uptime Publishing Bot --- uptime_setup.py | 188 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 uptime_setup.py diff --git a/uptime_setup.py b/uptime_setup.py new file mode 100644 index 0000000..bfbe972 --- /dev/null +++ b/uptime_setup.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import getpass +from mastodon import Mastodon +from mastodon.Mastodon import MastodonMalformedEventError, MastodonNetworkError, MastodonReadTimeout, MastodonAPIError, MastodonIllegalArgumentError +import fileinput,re +import os +import sys + +def create_dir(): + if not os.path.exists('secrets'): + os.makedirs('secrets') + +def create_file(): + if not os.path.exists('secrets/uptime_secrets.txt'): + with open('secrets/uptime_secrets.txt', 'w'): pass + print(secrets_filepath + " created!") + +def create_config(): + if not os.path.exists('config'): + os.makedirs('config') + if not os.path.exists(config_filepath): + print(config_filepath + " created!") + with open('config/config.txt', 'w'): pass + +def write_params(): + with open(secrets_filepath, 'a') as the_file: + print("Writing secrets parameter names to " + secrets_filepath) + the_file.write('uc_client_id: \n'+'uc_client_secret: \n'+'uc_access_token: \n') + +def write_config(): + with open(config_filepath, 'a') as the_file: + the_file.write('mastodon_hostname: \n') + print("adding parameter name 'mastodon_hostname' to "+ config_filepath) + +def read_client_lines(self): + client_path = 'app_clientcred.txt' + with open(client_path) as fp: + line = fp.readline() + cnt = 1 + while line: + if cnt == 1: + print("Writing client id to " + secrets_filepath) + modify_file(secrets_filepath, "uc_client_id: ", value=line.rstrip()) + elif cnt == 2: + print("Writing client secret to " + secrets_filepath) + modify_file(secrets_filepath, "uc_client_secret: ", value=line.rstrip()) + line = fp.readline() + cnt += 1 + +def read_token_line(self): + token_path = 'app_usercred.txt' + with open(token_path) as fp: + line = fp.readline() + print("Writing access token to " + secrets_filepath) + modify_file(secrets_filepath, "uc_access_token: ", value=line.rstrip()) + +def read_config_line(): + with open(config_filepath) as fp: + line = fp.readline() + modify_file(config_filepath, "mastodon_hostname: ", value=hostname) + +def log_in(): + error = 0 + try: + global hostname + hostname = input("Enter Mastodon hostname: ") + user_name = input("User name, ex. user@" + hostname +"? ") + user_password = getpass.getpass("User password? ") + app_name = input("This app name? ") + Mastodon.create_app(app_name, scopes=["read","write"], + to_file="app_clientcred.txt", api_base_url=hostname) + mastodon = Mastodon(client_id = "app_clientcred.txt", api_base_url = hostname) + mastodon.log_in( + user_name, + user_password, + scopes = ["read", "write"], + to_file = "app_usercred.txt" + ) + except MastodonIllegalArgumentError as i_error: + error = 1 + if os.path.exists("secrets/uptime_secrets.txt"): + print("Removing secrets/uptime_secrets.txt file..") + os.remove("secrets/uptime_secrets.txt") + if os.path.exists("app_clientcred.txt"): + print("Removing app_clientcred.txt file..") + os.remove("app_clientcred.txt") + sys.exit(i_error) + except MastodonNetworkError as n_error: + error = 1 + if os.path.exists("secrets/uptime_secrets.txt"): + print("Removing secrets/uptime_secrets.txt file..") + os.remove("secrets/uptime_secrets.txt") + if os.path.exists("app_clientcred.txt"): + print("Removing app_clientcred.txt file..") + os.remove("app_clientcred.txt") + sys.exit(n_error) + except MastodonReadTimeout as r_error: + error = 1 + if os.path.exists("secrets/uptime_secrets.txt"): + print("Removing secrets/uptime_secrets.txt file..") + os.remove("secrets/uptime_secrets.txt") + if os.path.exists("app_clientcred.txt"): + print("Removing app_clientcred.txt file..") + os.remove("app_clientcred.txt") + sys.exit(r_error) + except MastodonAPIError as a_error: + error = 1 + if os.path.exists("secrets/uptime_secrets.txt"): + print("Removing secrets/uptime_secrets.txt file..") + os.remove("secrets/uptime_secrets.txt") + if os.path.exists("app_clientcred.txt"): + print("Removing app_clientcred.txt file..") + os.remove("app_clientcred.txt") + sys.exit(a_error) + finally: + if error == 0: + + create_dir() + create_file() + write_params() + client_path = 'app_clientcred.txt' + read_client_lines(client_path) + token_path = 'app_usercred.txt' + read_token_line(token_path) + if os.path.exists("app_clientcred.txt"): + print("Removing app_clientcred.txt temp file..") + os.remove("app_clientcred.txt") + if os.path.exists("app_usercred.txt"): + print("Removing app_usercred.txt temp file..") + os.remove("app_usercred.txt") + print("uptime secrets setup done!\n") + +def modify_file(file_name,pattern,value=""): + fh=fileinput.input(file_name,inplace=True) + for line in fh: + replacement=pattern + value + line=re.sub(pattern,replacement,line) + sys.stdout.write(line) + fh.close() + +# 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, creating it."%file_path) + log_in() + + # 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) + +# Returns the parameter from the specified file +def get_hostname( parameter, config_filepath ): + # Check if secrets file exists + if not os.path.isfile(config_filepath): + print("File %s not found, creating it."%config_filepath) + create_config() + + # Find parameter in file + with open( config_filepath ) as f: + for line in f: + if line.startswith( parameter ): + return line.replace(parameter + ":", "").strip() + + # Cannot find parameter, exit + print(config_filepath + " Missing parameter %s "%parameter) + write_config() + read_config_line() + print("setup done!") + sys.exit(0) + +# 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_hostname("mastodon_hostname", config_filepath) From 1bf67f2f2808809048d9582b13c44bd719738286 Mon Sep 17 00:00:00 2001 From: spla Date: Sat, 21 Aug 2021 12:53:56 +0200 Subject: [PATCH 04/11] Added Best Fediverse Server Uptime Publishing Bot --- fediverse.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/fediverse.py b/fediverse.py index 7e1bfd5..16c1ad7 100644 --- a/fediverse.py +++ b/fediverse.py @@ -53,7 +53,7 @@ def get_alive_servers(server): cur = conn.cursor() - cur.execute("select alive, software, users_api, version from fediverse where server=(%s)", (server,)) + cur.execute("select alive, software, users_api, version, first_checked_at from fediverse where server=(%s)", (server,)) row = cur.fetchone() @@ -63,6 +63,7 @@ def get_alive_servers(server): serv_soft = row[1] serv_api = row[2] soft_version = row[3] + first_checked_at = row[4] cur.close() @@ -79,7 +80,9 @@ def get_alive_servers(server): try: - data = requests.get('https://' + server + serv_api, timeout=3) + user_agent = {'User-agent': 'Mozilla/5.0'} + + data = requests.get('https://' + server + serv_api, headers = user_agent, timeout=3) if serv_soft == "mastodon": if serv_api == '/nodeinfo/2.0?': @@ -160,7 +163,7 @@ def get_alive_servers(server): else: print("Server " + str(server) + " (" + serv_soft + ") is alive!") - insert_sql = "INSERT INTO fediverse(server, users, updated_at, software, alive, users_api, version) VALUES(%s,%s,%s,%s,%s,%s,%s) ON CONFLICT DO NOTHING" + insert_sql = "INSERT INTO fediverse(server, users, updated_at, software, alive, users_api, version, first_checked_at, last_checked_at) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s) ON CONFLICT DO NOTHING" conn = None @@ -170,9 +173,16 @@ def get_alive_servers(server): cur = conn.cursor() - cur.execute(insert_sql, (server, users, now, serv_soft, alive, serv_api, soft_version)) + cur.execute(insert_sql, (server, users, now, serv_soft, alive, serv_api, soft_version, now, now)) + + if first_checked_at != None: + + cur.execute("UPDATE fediverse SET users=(%s), updated_at=(%s), software=(%s), alive=(%s), users_api=(%s), version=(%s), last_checked_at=(%s) where server=(%s)", (users, now, serv_soft, alive, serv_api, soft_version, now, server)) + + else: + + cur.execute("UPDATE fediverse SET users=(%s), updated_at=(%s), software=(%s), alive=(%s), users_api=(%s), version=(%s), first_checked_at=(%s), last_checked_at=(%s) where server=(%s)", (users, now, serv_soft, alive, serv_api, soft_version, now, now, server)) - cur.execute("UPDATE fediverse SET users=(%s), updated_at=(%s), software=(%s), alive=(%s), users_api=(%s), version=(%s) where server=(%s)", (users, now, serv_soft, alive, serv_api, soft_version, server)) cur.execute("UPDATE world SET checked='t' where server=(%s)", (server,)) @@ -267,7 +277,13 @@ def get_alive_servers(server): cur = conn.cursor() - cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s) where server=(%s)", (now, alive, server)) + if first_checked_at != None: + + cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s), first_checked_at=(%s) where server=(%s)", (now, alive, NULL, server)) + + else: + + cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s) where server=(%s)", (now, alive, server)) cur.execute("UPDATE world SET checked='t' where server=(%s)", (server,)) From 8c7b01cbc7275aca96f609d4f0c113d3b5aceb62 Mon Sep 17 00:00:00 2001 From: spla Date: Sat, 21 Aug 2021 12:57:29 +0200 Subject: [PATCH 05/11] Added Best Fediverse Server Uptime Publishing Bot --- db-setup.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/db-setup.py b/db-setup.py index a17320c..80ab5f9 100644 --- a/db-setup.py +++ b/db-setup.py @@ -138,11 +138,11 @@ print("Creating table...") db = fediverse_db db_user = fediverse_db_user table = "world" -sql = "create table "+table+" (server varchar(200) PRIMARY KEY, federated_with varchar(200), updated_at timestamptz, saved_at timestamptz), checked boolean" +sql = "create table "+table+" (server varchar(200) PRIMARY KEY, federated_with varchar(200), updated_at timestamptz, saved_at timestamptz, checked boolean)" create_table(db, db_user, table, sql) table = "fediverse" -sql = "create table "+table+" (server varchar(200) PRIMARY KEY, users INT, updated_at timestamptz, software varchar(50), version varchar(100))" +sql = "create table "+table+" (server varchar(200) PRIMARY KEY, users INT, updated_at timestamptz, software varchar(50), version varchar(100), first_checked_at timestamptz, last_checked_at timestamptz)" create_table(db, db_user, table, sql) table = "totals" @@ -153,6 +153,10 @@ table = "evo" sql = "create table "+table+" (datetime timestamptz PRIMARY KEY, servers INT, users INT)" create_table(db, db_user, table, sql) +table = "closed" +sql = "create table "+table+" (server varchar(200) PRIMARY KEY, software varchar(10), closed boolean)" +create_table(db, db_user, table, sql) + ##################################### print("Done!") From 72279e5e3ccb00105ea186aa1c796afa433154ff Mon Sep 17 00:00:00 2001 From: spla Date: Sun, 22 Aug 2021 12:46:43 +0200 Subject: [PATCH 06/11] Human friendly uptime --- requirements.txt | 1 + uptime.py | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d1dfc34..9bfc392 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ psycopg2-binary>=2.8.4 aiohttp>=3.6.2 aiodns>=2.0.0 matplotlib>=3.3.4 +humanfriendly>=9.2 diff --git a/uptime.py b/uptime.py index 4cba8a8..2fe4419 100644 --- a/uptime.py +++ b/uptime.py @@ -1,6 +1,7 @@ import time import os from datetime import datetime, timedelta +import humanfriendly from mastodon import Mastodon import psycopg2 @@ -64,6 +65,40 @@ def get_uptime(): 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 @@ -129,7 +164,7 @@ if __name__ == '__main__': toot_text = '\nAlive servers: ' + str(alive_servers) toot_text += '\n\n' - toot_text += "Best #fediverse's server uptime:\n" + str(max_uptime) + toot_text += "Best #fediverse's server uptime:\n" + humanfriendly.format_timespan(max_uptime) toot_text += '\n' toot_text += 'Servers with best uptime: ' + str(best_servers) toot_text += '\n\n' @@ -137,7 +172,8 @@ if __name__ == '__main__': i = 0 while i < len(software_lst): - toot_text += ':' + str(software_lst[i]) + ': ' + str(servers_lst[i]) + '\n' + 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) > 480: break From c6ec648fe23e67a8bd08c223192af17c17a56f95 Mon Sep 17 00:00:00 2001 From: spla Date: Mon, 23 Aug 2021 17:23:42 +0200 Subject: [PATCH 07/11] New column 'downs' to store down servers --- db-setup.py | 2 +- fediverse.py | 31 ++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/db-setup.py b/db-setup.py index 80ab5f9..71a1a77 100644 --- a/db-setup.py +++ b/db-setup.py @@ -142,7 +142,7 @@ sql = "create table "+table+" (server varchar(200) PRIMARY KEY, federated_with v create_table(db, db_user, table, sql) table = "fediverse" -sql = "create table "+table+" (server varchar(200) PRIMARY KEY, users INT, updated_at timestamptz, software varchar(50), version varchar(100), first_checked_at timestamptz, last_checked_at timestamptz)" +sql = "create table "+table+" (server varchar(200) PRIMARY KEY, users INT, updated_at timestamptz, software varchar(50), version varchar(100), first_checked_at timestamptz, last_checked_at timestamptz, downs int)" create_table(db, db_user, table, sql) table = "totals" diff --git a/fediverse.py b/fediverse.py index 16c1ad7..9a2f6df 100644 --- a/fediverse.py +++ b/fediverse.py @@ -53,7 +53,7 @@ def get_alive_servers(server): cur = conn.cursor() - cur.execute("select alive, software, users_api, version, first_checked_at from fediverse where server=(%s)", (server,)) + cur.execute("select alive, software, users_api, version, first_checked_at, downs from fediverse where server=(%s)", (server,)) row = cur.fetchone() @@ -64,6 +64,7 @@ def get_alive_servers(server): serv_api = row[2] soft_version = row[3] first_checked_at = row[4] + downs_qty = row[5] cur.close() @@ -158,12 +159,20 @@ def get_alive_servers(server): if alive: + if downs_qty != None: + + downs = downs_qty + + else: + + downs = 0 + if soft_version != "" and soft_version is not None: print("Server " + str(server) + " (" + serv_soft + " " + soft_version + ") is alive!") else: print("Server " + str(server) + " (" + serv_soft + ") is alive!") - insert_sql = "INSERT INTO fediverse(server, users, updated_at, software, alive, users_api, version, first_checked_at, last_checked_at) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s) ON CONFLICT DO NOTHING" + insert_sql = "INSERT INTO fediverse(server, users, updated_at, software, alive, users_api, version, first_checked_at, last_checked_at, downs) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ON CONFLICT DO NOTHING" conn = None @@ -173,15 +182,15 @@ def get_alive_servers(server): cur = conn.cursor() - cur.execute(insert_sql, (server, users, now, serv_soft, alive, serv_api, soft_version, now, now)) + cur.execute(insert_sql, (server, users, now, serv_soft, alive, serv_api, soft_version, now, now, downs)) if first_checked_at != None: - cur.execute("UPDATE fediverse SET users=(%s), updated_at=(%s), software=(%s), alive=(%s), users_api=(%s), version=(%s), last_checked_at=(%s) where server=(%s)", (users, now, serv_soft, alive, serv_api, soft_version, now, server)) + cur.execute("UPDATE fediverse SET users=(%s), updated_at=(%s), software=(%s), alive=(%s), users_api=(%s), version=(%s), last_checked_at=(%s), downs=(%s) where server=(%s)", (users, now, serv_soft, alive, serv_api, soft_version, now, downs, server)) else: - cur.execute("UPDATE fediverse SET users=(%s), updated_at=(%s), software=(%s), alive=(%s), users_api=(%s), version=(%s), first_checked_at=(%s), last_checked_at=(%s) where server=(%s)", (users, now, serv_soft, alive, serv_api, soft_version, now, now, server)) + cur.execute("UPDATE fediverse SET users=(%s), updated_at=(%s), software=(%s), alive=(%s), users_api=(%s), version=(%s), first_checked_at=(%s), last_checked_at=(%s), downs=(%s) where server=(%s)", (users, now, serv_soft, alive, serv_api, soft_version, now, now, downs, server)) cur.execute("UPDATE world SET checked='t' where server=(%s)", (server,)) @@ -268,6 +277,14 @@ def get_alive_servers(server): if alive is False: + if downs_qty != None: + + downs = downs_qty + 1 + + else: + + downs = 1 + conn = None try: @@ -279,11 +296,11 @@ def get_alive_servers(server): if first_checked_at != None: - cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s), first_checked_at=(%s) where server=(%s)", (now, alive, NULL, server)) + cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s), first_checked_at=(%s), downs=(%s) where server=(%s)", (now, alive, NULL, downs, server)) else: - cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s) where server=(%s)", (now, alive, server)) + cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s), downs=(%s) where server=(%s)", (now, alive, downs, server)) cur.execute("UPDATE world SET checked='t' where server=(%s)", (server,)) From 7c75ca678c0efb6a29bc843e4d5c6ca7c7f2ce3f Mon Sep 17 00:00:00 2001 From: spla Date: Tue, 24 Aug 2021 19:11:33 +0200 Subject: [PATCH 08/11] Added user agent --- fetchservers.py | 4 +++- getpeers.py | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fetchservers.py b/fetchservers.py index 1a89af6..e1d2cee 100644 --- a/fetchservers.py +++ b/fetchservers.py @@ -79,8 +79,10 @@ async def getsoft(server): url = 'https://' + server + user_agent = {'User-agent': 'Mozilla/5.0'} + timeout = aiohttp.ClientTimeout(total=3) - async with aiohttp.ClientSession(timeout=timeout) as session: + async with aiohttp.ClientSession(timeout=timeout, headers=user_agent) as session: for api in apis: try: async with session.get(url + api) as response: diff --git a/getpeers.py b/getpeers.py index cd60fe8..0146cea 100644 --- a/getpeers.py +++ b/getpeers.py @@ -50,7 +50,9 @@ def get_peers(peer): try: - response = requests.get('https://' + peer + peers_api, timeout=2) + user_agent = {'User-agent': 'Mozilla/5.0'} + + response = requests.get('https://' + peer + peers_api, headers = user_agent, timeout=3) response_json = response.json() @@ -126,7 +128,9 @@ if __name__ == '__main__': world_peers = [] - res = requests.get('https://' + mastodon_hostname + peers_api) + user_agent = {'User-agent': 'Mozilla/5.0'} + + res = requests.get('https://' + mastodon_hostname + peers_api, headers = user_agent, timeout=3) hostname_peers = res.json() From e6f82478ea6e2bb25b328db7a785481167b9481f Mon Sep 17 00:00:00 2001 From: spla Date: Tue, 31 Aug 2021 11:11:24 +0200 Subject: [PATCH 09/11] Added image description to graphs --- fediverse.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fediverse.py b/fediverse.py index 9a2f6df..50cdb48 100644 --- a/fediverse.py +++ b/fediverse.py @@ -14,7 +14,7 @@ import aiohttp import asyncio import socket import matplotlib.pyplot as plt - +import pdb plt.style.use('seaborn') start_time = time.time() @@ -919,8 +919,8 @@ if __name__ == '__main__': print("Tooting...") print(toot_text) - servers_image_id = mastodon.media_post('servers.png', "image/png").id + servers_image_id = mastodon.media_post('servers.png', "image/png", description='servers graph').id - users_image_id = mastodon.media_post('users.png', "image/png").id + users_image_id = mastodon.media_post('users.png', "image/png", description='users graph').id mastodon.status_post(toot_text, in_reply_to_id=None, media_ids={servers_image_id, users_image_id}) From 203f19381a696311d603b52cec8c32180b1b7ac9 Mon Sep 17 00:00:00 2001 From: spla Date: Mon, 6 Sep 2021 21:41:04 +0200 Subject: [PATCH 10/11] If server is not alive update first_checked_at column to now() --- fediverse.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fediverse.py b/fediverse.py index 50cdb48..2933927 100644 --- a/fediverse.py +++ b/fediverse.py @@ -40,11 +40,11 @@ def is_json(myjson): return True def get_alive_servers(server): - + serv_api = '' serv_soft = '' soft_version = '' - + try: conn = None @@ -296,7 +296,7 @@ def get_alive_servers(server): if first_checked_at != None: - cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s), first_checked_at=(%s), downs=(%s) where server=(%s)", (now, alive, NULL, downs, server)) + cur.execute("UPDATE fediverse SET updated_at=(%s), alive=(%s), first_checked_at=(%s), downs=(%s) where server=(%s)", (now, alive, now, downs, server)) else: From 1edc396aeadc9953a2da80a03ea716c7948e6c78 Mon Sep 17 00:00:00 2001 From: spla Date: Tue, 7 Sep 2021 20:38:06 +0200 Subject: [PATCH 11/11] Added percentage of best uptime servers --- uptime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uptime.py b/uptime.py index 2fe4419..2dae65a 100644 --- a/uptime.py +++ b/uptime.py @@ -166,7 +166,7 @@ if __name__ == '__main__': toot_text += '\n\n' toot_text += "Best #fediverse's server uptime:\n" + humanfriendly.format_timespan(max_uptime) toot_text += '\n' - toot_text += 'Servers with best uptime: ' + str(best_servers) + toot_text += 'Servers with best uptime: ' + str(best_servers) + ' (' + str(round((best_servers*100)/alive_servers,2)) + '%)' toot_text += '\n\n' toot_text += 'software & servers with best uptime:' + '\n' i = 0