2022-03-11 19:53:21 +01:00
import sys
import os
2020-05-17 21:40:19 +02:00
import time
2020-05-17 21:28:03 +02:00
from datetime import datetime
2022-03-11 19:53:21 +01:00
import urllib3
2020-05-17 21:28:03 +02:00
import requests
2020-06-03 19:20:32 +02:00
import socket
2022-03-11 19:53:21 +01:00
from mastodon import Mastodon
import psycopg2
2021-05-12 16:17:33 +02:00
import matplotlib . pyplot as plt
2022-03-11 19:53:21 +01:00
import ray
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
ray . init ( num_cpus = 32 ) # Specify this system CPUs.
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
class Server :
2021-05-14 13:14:31 +02:00
2022-03-02 22:26:05 +01:00
name = ' Server '
2020-05-17 21:28:03 +02:00
2022-03-03 11:30:59 +01:00
def __init_ ( self , server , software , users , alive , api , soft_version , now ) :
2021-05-14 13:14:31 +02:00
2022-03-02 22:26:05 +01:00
self . server = server
self . software = software
self . users = users
self . alive = alive
self . api = api
self . version = self . soft_version
2022-03-03 11:30:59 +01:00
self . now = now
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
@ray.remote
def get_alive_servers ( server ) :
2021-05-14 13:14:31 +02:00
2022-03-11 19:53:21 +01:00
users = 0
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
downs = 0
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
fediverse_db , fediverse_db_user = db_config ( )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
try :
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
conn = None
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
cur = conn . cursor ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( " select alive, software, users_api, version, first_checked_at, downs from fediverse where server=( %s ) " , ( server , ) )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
row = cur . fetchone ( )
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
if row is not None :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
was_alive = row [ 0 ]
2022-03-11 19:53:21 +01:00
software = row [ 1 ]
api = row [ 2 ]
soft_version = row [ 3 ]
2022-03-02 22:26:05 +01:00
first_checked_at = row [ 4 ]
downs_qty = row [ 5 ]
2021-05-12 16:17:33 +02:00
2022-03-02 22:26:05 +01:00
cur . close ( )
2021-05-12 16:17:33 +02:00
2022-03-02 22:26:05 +01:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2021-05-12 16:17:33 +02:00
2022-03-02 22:26:05 +01:00
print ( error )
2021-05-12 16:17:33 +02:00
2022-03-02 22:26:05 +01:00
finally :
2021-05-12 16:17:33 +02:00
2022-03-02 22:26:05 +01:00
if conn is not None :
2021-05-12 16:17:33 +02:00
2022-03-02 22:26:05 +01:00
conn . close ( )
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
alive = False
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
try :
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
user_agent = { ' User-agent ' : ' Mozilla/5.0 ' }
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
data = requests . get ( ' https:// ' + server + api , headers = user_agent , timeout = 3 )
2021-10-26 13:38:12 +02:00
try :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
users = data . json ( ) [ ' usage ' ] [ ' users ' ] [ ' total ' ]
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
if users == 0 :
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
users = data . json ( ) [ ' usage ' ] [ ' users ' ] [ ' activeHalfyear ' ]
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
if software == ' socialhome ' :
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
soft_version = data . json ( ) [ ' server ' ] [ ' version ' ]
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
else :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
soft_version = data . json ( ) [ ' software ' ] [ ' version ' ]
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
if software == " wordpress " and " activitypub " in data . json ( ) [ ' protocols ' ] :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
alive = True
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
elif software == " wordpress " and " activitypub " not in data . json ( ) [ ' protocols ' ] :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
alive = False
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
else :
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
alive = True
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
except :
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
soft_version = " "
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
else :
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
if api == ' /api/v1/instance? ' :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
try :
2022-03-11 19:53:21 +01:00
users = data . json ( ) [ ' stats ' ] [ ' user_count ' ]
soft_version = data . json ( ) [ ' version ' ]
2022-03-02 22:26:05 +01:00
alive = True
except :
2022-03-11 19:53:21 +01:00
soft_version = " "
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
if alive :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
if downs_qty != None :
2021-05-12 16:17:33 +02:00
2022-03-02 22:26:05 +01:00
downs = downs_qty
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
if soft_version != " " and soft_version is not None :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
print ( f ' \n ** Server { server } ( { software } { soft_version } ) is alive! ** ' )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
else :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
print ( f ' \n ** Server { server } ( { software } ) is alive! ** ' )
2021-10-26 13:38:12 +02:00
2022-03-12 12:58:16 +01:00
write_alive_server ( server , software , soft_version , alive , api , users , downs , first_checked_at )
2022-03-02 22:26:05 +01:00
except urllib3 . exceptions . ProtocolError as protoerr :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
except requests . exceptions . ChunkedEncodingError as chunkerr :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
except KeyError as e :
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
except ValueError as verr :
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
except requests . exceptions . SSLError as errssl :
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
except requests . exceptions . HTTPError as errh :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
except requests . exceptions . ConnectionError as errc :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
except requests . exceptions . Timeout as errt :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
except requests . exceptions . RequestException as err :
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
except socket . gaierror as gai_error :
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
print_dead ( server )
2022-03-02 22:26:05 +01:00
pass
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
if not alive :
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
if downs_qty != None :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
downs = downs_qty + 1
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
else :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
downs = 1
2020-06-04 19:38:53 +02:00
2022-03-12 12:58:16 +01:00
write_not_alive_server ( server , software , soft_version , alive , api , users , downs , first_checked_at )
2022-03-11 19:53:21 +01:00
return ( server , software , soft_version , alive , api , users , downs , first_checked_at )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
def write_alive_server ( server , software , soft_version , alive , api , users , downs , first_checked_at ) :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
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 "
2020-06-04 19:38:53 +02:00
2022-03-11 19:53:21 +01:00
conn = None
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
try :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
cur = conn . cursor ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( insert_sql , ( server , users , now , software , alive , api , soft_version , now , now , downs ) )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
if first_checked_at != None :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
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 , software , alive , api , soft_version , now , downs , server ) )
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
else :
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
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 , software , alive , api , soft_version , now , now , downs , server ) )
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( " UPDATE world SET checked= ' t ' where server=( %s ) " , ( server , ) )
2021-10-26 13:38:12 +02:00
2022-03-11 19:53:21 +01:00
conn . commit ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
cur . close ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
print ( error )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
finally :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
if conn is not None :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
conn . close ( )
def write_not_alive_server ( server , software , soft_version , alive , api , users , downs , first_checked_at ) :
conn = None
2020-05-17 21:28:03 +02:00
2020-06-03 19:20:32 +02:00
try :
2022-03-11 19:53:21 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
cur = conn . cursor ( )
if first_checked_at != None :
cur . execute ( " UPDATE fediverse SET updated_at=( %s ), alive=( %s ), downs=( %s ) where server=( %s ) " , ( now , alive , downs , server ) )
else :
cur . execute ( " UPDATE fediverse SET updated_at=( %s ), alive=( %s ), first_checked_at=( %s ), downs=( %s ) where server=( %s ) " , ( now , alive , now , downs , server ) )
cur . execute ( " UPDATE world SET checked= ' t ' where server=( %s ) " , ( server , ) )
conn . commit ( )
cur . close ( )
except ( Exception , psycopg2 . DatabaseError ) as error :
print ( error )
finally :
if conn is not None :
conn . close ( )
def delete_dead_servers ( ) :
conn = None
try :
2020-06-03 19:20:32 +02:00
2021-05-14 13:14:31 +02:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2020-06-03 19:20:32 +02:00
cur = conn . cursor ( )
2022-03-11 19:53:21 +01:00
cur . execute ( " select server from fediverse where downs > ' 14 ' and not alive and now() - first_checked_at > interval ' 7 days ' " )
rows = cur . fetchall ( )
for row in rows :
print ( f ' Deleting server { row [ 0 ] } ... ' )
cur . execute ( " delete from fediverse where server=( %s ) " , ( row [ 0 ] , ) )
2020-06-03 19:20:32 +02:00
conn . commit ( )
2020-05-17 21:28:03 +02:00
2020-06-03 19:20:32 +02:00
cur . close ( )
2020-05-17 21:28:03 +02:00
2020-06-03 19:20:32 +02:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2020-05-17 21:28:03 +02:00
2020-06-03 19:20:32 +02:00
print ( error )
finally :
if conn is not None :
conn . close ( )
2021-05-12 16:17:33 +02:00
def get_last_checked_servers ( ) :
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
############################################################################
# get last checked servers from fediverse DB
2020-06-03 19:20:32 +02:00
alive_servers = [ ]
try :
conn = None
2022-03-11 19:53:21 +01:00
2021-05-14 13:14:31 +02:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2020-06-03 19:20:32 +02:00
cur = conn . cursor ( )
2021-05-14 13:14:31 +02:00
# get world servers list
2020-06-03 19:20:32 +02:00
cur . execute ( " select server from world where server in (select server from fediverse where users_api != ' ' ) " )
alive_servers = [ ]
for row in cur :
alive_servers . append ( row [ 0 ] )
cur . close ( )
except ( Exception , psycopg2 . DatabaseError ) as error :
print ( error )
finally :
if conn is not None :
conn . close ( )
2021-05-12 16:17:33 +02:00
return alive_servers
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
def print_dead ( server ) :
print ( f ' \n Server { server } is dead :-( ' )
def set_world_servers_check_to_false ( ) :
############################################################################
# set all world servers's checked column to False
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 ( " UPDATE world SET checked= ' f ' " )
conn . commit ( )
cur . close ( )
except ( Exception , psycopg2 . DatabaseError ) as error :
print ( error )
finally :
if conn is not None :
conn . close ( )
def set_world_servers_check_to_false ( ) :
############################################################################
# set all world servers's checked column to False
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 ( " UPDATE world SET checked= ' f ' " )
conn . commit ( )
cur . close ( )
except ( Exception , psycopg2 . DatabaseError ) as error :
print ( error )
finally :
if conn is not None :
conn . close ( )
2021-05-12 16:17:33 +02:00
def mastodon ( ) :
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
# Load secrets from secrets file
secrets_filepath = " secrets/secrets.txt "
2021-05-14 13:14:31 +02:00
uc_client_id = get_parameter ( " uc_client_id " , secrets_filepath )
2021-05-12 16:17:33 +02:00
uc_client_secret = get_parameter ( " uc_client_secret " , secrets_filepath )
2021-05-14 13:14:31 +02:00
uc_access_token = get_parameter ( " uc_access_token " , secrets_filepath )
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
# Load configuration from config file
config_filepath = " config/config.txt "
mastodon_hostname = get_parameter ( " mastodon_hostname " , config_filepath )
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
# Initialise Mastodon API
mastodon = Mastodon (
2021-05-14 13:14:31 +02:00
client_id = uc_client_id ,
client_secret = uc_client_secret ,
access_token = uc_access_token ,
api_base_url = ' https:// ' + mastodon_hostname ,
2021-05-12 16:17:33 +02:00
)
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
# Initialise access headers
2021-05-14 13:14:31 +02:00
headers = { ' Authorization ' : ' Bearer %s ' % uc_access_token }
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
return ( mastodon , mastodon_hostname )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
def db_config ( ) :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
# 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 )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
return ( fediverse_db , fediverse_db_user )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
def usage ( ) :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
print ( ' usage: python ' + sys . argv [ 0 ] + ' --multi ' + ' (multiprocessing, fast) ' )
print ( ' usage: python ' + sys . argv [ 0 ] + ' --mono ' + ' (one process, slow) ' )
2020-05-17 21:28:03 +02:00
2021-05-14 13:14:31 +02:00
def get_parameter ( parameter , file_path ) :
2021-05-12 16:17:33 +02:00
# Check if secrets file exists
if not os . path . isfile ( file_path ) :
print ( " File %s not found, exiting. " % file_path )
sys . exit ( 0 )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
# Find parameter in file
2021-05-14 13:14:31 +02:00
with open ( file_path ) as f :
2021-05-12 16:17:33 +02:00
for line in f :
2021-05-14 13:14:31 +02:00
if line . startswith ( parameter ) :
2021-05-12 16:17:33 +02:00
return line . replace ( parameter + " : " , " " ) . strip ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
# Cannot find parameter, exit
print ( file_path + " Missing parameter %s " % parameter )
sys . exit ( 0 )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
if __name__ == ' __main__ ' :
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
# usage modes
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
if len ( sys . argv ) == 1 :
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
usage ( )
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
elif len ( sys . argv ) == 2 :
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
if sys . argv [ 1 ] == ' --multi ' :
2022-03-02 22:26:05 +01:00
2022-03-03 11:30:59 +01:00
now = datetime . now ( )
2021-05-12 16:17:33 +02:00
mastodon , mastodon_hostname = mastodon ( )
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
fediverse_db , fediverse_db_user = db_config ( )
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
total_servers = 0
2022-03-11 19:53:21 +01:00
2021-05-12 16:17:33 +02:00
total_users = 0
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
set_world_servers_check_to_false ( )
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
alive_servers = get_last_checked_servers ( )
2022-03-02 22:26:05 +01:00
getservers = Server ( )
2022-03-03 11:30:59 +01:00
getservers . now = datetime . now ( )
2022-03-11 19:53:21 +01:00
start = time . time ( )
results = ray . get ( [ getservers . get_alive_servers . remote ( server ) for server in alive_servers ] )
print ( f " duration = { time . time ( ) - start } . \n processed servers: { len ( results ) } " )
###########################################################################
# get current total servers and users, get users from every software
2021-05-12 16:17:33 +02:00
now = datetime . now ( )
2022-03-11 19:53:21 +01:00
gettotals_sql = " select count(server), sum(users) from fediverse where alive "
get_soft_totals_sql = " select software, sum(users) as users, count(server) as servers from fediverse where users != 0 and alive group by software order by users desc "
soft_total_project = [ ]
soft_total_users = [ ]
soft_total_servers = [ ]
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
try :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn = None
2022-03-02 22:26:05 +01:00
2022-03-11 19:53:21 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur = conn . cursor ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( gettotals_sql )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
row = cur . fetchone ( )
2022-03-02 22:26:05 +01:00
2022-03-11 19:53:21 +01:00
total_servers = row [ 0 ]
2022-03-03 11:30:59 +01:00
2022-03-11 19:53:21 +01:00
total_users = row [ 1 ]
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( get_soft_totals_sql )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
rows = cur . fetchall ( )
2022-03-02 22:26:05 +01:00
2022-03-11 19:53:21 +01:00
for row in rows :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
soft_total_project . append ( row [ 0 ] )
soft_total_users . append ( row [ 1 ] )
soft_total_servers . append ( row [ 2 ] )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . close ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
print ( error )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
finally :
2022-03-02 22:26:05 +01:00
2022-03-11 19:53:21 +01:00
if conn is not None :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn . close ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
###########################################################################
# get last check values and write current total ones
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
select_sql = " select total_servers, total_users from totals order by datetime desc limit 1 "
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
insert_sql = " INSERT INTO totals(datetime, total_servers, total_users) VALUES( %s , %s , %s ) "
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
try :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn = None
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur = conn . cursor ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( select_sql )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
row = cur . fetchone ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
if row is not None :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
servers_before = row [ 0 ]
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
users_before = row [ 1 ]
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
else :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
servers_before = 0
users_before = 0
cur . execute ( insert_sql , ( now , total_servers , total_users ) )
conn . commit ( )
cur . close ( )
evo_servers = total_servers - servers_before
evo_users = total_users - users_before
except ( Exception , psycopg2 . DatabaseError ) as error :
print ( error )
finally :
if conn is not None :
conn . close ( )
################################################################################
# write evo values
insert_sql = " INSERT INTO evo(datetime, servers, users) VALUES( %s , %s , %s ) "
2021-05-12 16:17:33 +02:00
conn = None
2022-03-11 19:53:21 +01:00
try :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur = conn . cursor ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( insert_sql , ( now , evo_servers , evo_users ) )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn . commit ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . close ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
print ( error )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
finally :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
if conn is not None :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn . close ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
##############################################################################
# get world's last update datetime
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn = None
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
try :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur = conn . cursor ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( " select updated_at from world order by updated_at desc limit 1 " )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
row = cur . fetchone ( )
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
last_update = row [ 0 ]
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
last_update = last_update . strftime ( ' % m/ %d / % Y, % H: % M: % S ' )
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
cur . close ( )
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
print ( error )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
finally :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
if conn is not None :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
conn . close ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
##############################################################################
# get max servers and users
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
conn = None
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
try :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
cur = conn . cursor ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( " select MAX(total_servers) from totals " )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
row = cur . fetchone ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
if row is not None :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
max_servers = row [ 0 ]
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
else :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
max_servers = 0
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( " select MAX(total_users) from totals " )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
row = cur . fetchone ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
if row is not None :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
max_users = row [ 0 ]
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
else :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
max_users = 0
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . close ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
print ( error )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
finally :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
if conn is not None :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
conn . close ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
###############################################################################
# get plots
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
servers_plots = [ ]
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
users_plots = [ ]
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
conn = None
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
try :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
conn = psycopg2 . connect ( database = fediverse_db , user = fediverse_db_user , password = " " , host = " /var/run/postgresql " , port = " 5432 " )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
cur = conn . cursor ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
cur . execute ( " select total_servers, total_users from totals order by datetime desc limit 14 " )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
rows = cur . fetchall ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
for row in rows :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
servers_plots . append ( row [ 0 ] )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
users_plots . append ( row [ 1 ] )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
cur . close ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
print ( error )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
finally :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
if conn is not None :
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
conn . close ( )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
###############################################################################
# generate graphs
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
plt . plot ( [ - 6 , - 5 , - 4 , - 3 , - 2 , - 1 , 0 ] , [ servers_plots [ 6 ] , servers_plots [ 5 ] , servers_plots [ 4 ] , servers_plots [ 3 ] , servers_plots [ 2 ] , servers_plots [ 1 ] , servers_plots [ 0 ] ] , marker = ' o ' , color = ' mediumseagreen ' )
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
plt . plot ( [ - 6 , - 5 , - 4 , - 3 , - 2 , - 1 , 0 ] , [ max_servers , max_servers , max_servers , max_servers , max_servers , max_servers , max_servers ] , color = ' red ' )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . title ( ' fediverse: total alive servers (max: ' + str ( f " { max_servers : , } " + ' ) ' ) , loc = ' right ' , color = ' blue ' )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . xlabel ( ' Last seven days ' )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . ylabel ( ' fediverse alive servers ' )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . legend ( ( ' servers ' , ' max ' ) , shadow = True , loc = ( 0.01 , 1.00 ) , handlelength = 1.5 , fontsize = 10 )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . savefig ( ' servers.png ' )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . close ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . plot ( [ - 6 , - 5 , - 4 , - 3 , - 2 , - 1 , 0 ] , [ users_plots [ 6 ] , users_plots [ 5 ] , users_plots [ 4 ] , users_plots [ 3 ] , users_plots [ 2 ] , users_plots [ 1 ] , users_plots [ 0 ] ] , marker = ' o ' , color = ' royalblue ' )
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
plt . plot ( [ - 6 , - 5 , - 4 , - 3 , - 2 , - 1 , 0 ] , [ max_users , max_users , max_users , max_users , max_users , max_users , max_users ] , color = ' red ' )
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
plt . title ( ' fediverse: total registered users (max: ' + str ( f " { max_users : , } " + ' ) ' ) , loc = ' right ' , color = ' royalblue ' )
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
plt . legend ( ( ' users ' , ' max ' ) , shadow = True , loc = ( 0.01 , 0.80 ) , handlelength = 1.5 , fontsize = 10 )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . xlabel ( ' Last seven days ' )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . ylabel ( ' Registered users ' )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . savefig ( ' users.png ' )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
plt . close ( )
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
###############################################################################
# T O O T !
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
toot_text = " #fediverse alive servers stats " + " \n "
2020-06-03 19:20:32 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
if evo_servers > = 0 :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " alive servers: " + str ( f " { total_servers : , } " ) + " (+ " + str ( f " { evo_servers : , } " ) + " ) \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " max: " + str ( f " { max_servers : , } " ) + " \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
elif evo_servers < 0 :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " alive servers: " + str ( f " { total_servers : , } " ) + " ( " + str ( f " { evo_servers : , } " ) + " ) \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " max: " + str ( f " { max_servers : , } " ) + " \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
if evo_users > = 0 :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " total users: " + str ( f " { total_users : , } " ) + " (+ " + str ( f " { evo_users : , } " ) + " ) \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " max: " + str ( f " { max_users : , } " ) + " \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
elif evo_users < 0 :
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " total users: " + str ( f " { total_users : , } " ) + " ( " + str ( f " { evo_users : , } " ) + " ) \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " max: " + str ( f " { max_users : , } " ) + " \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = " \n top ten (soft users servers): \n \n "
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
i = 0
2020-05-17 21:28:03 +02:00
2022-03-11 19:53:21 +01:00
while i < 10 :
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
project_soft = soft_total_project [ i ]
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
project_users = soft_total_users [ i ]
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
project_servers = soft_total_servers [ i ]
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
len_pr_soft = len ( project_soft )
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
toot_text + = f " : { project_soft } : { project_users : , } { project_servers : , } \n "
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
i + = 1
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
print ( " Tooting... " )
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
print ( toot_text )
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
servers_image_id = mastodon . media_post ( ' servers.png ' , " image/png " , description = ' servers graph ' ) . id
2021-05-12 16:17:33 +02:00
2022-03-11 19:53:21 +01:00
users_image_id = mastodon . media_post ( ' users.png ' , " image/png " , description = ' users graph ' ) . id
2020-05-19 23:33:55 +02:00
2022-03-11 19:53:21 +01:00
mastodon . status_post ( toot_text , in_reply_to_id = None , media_ids = { servers_image_id , users_image_id } )
delete_dead_servers ( )
else :
usage ( )