2022-03-02 22:26:05 +01:00
from multiprocessing import set_start_method
from multiprocessing import get_context
2020-05-17 21:40:19 +02:00
import time
2020-05-17 21:28:03 +02:00
import urllib3
from datetime import datetime
from mastodon import Mastodon
import os
import json
import sys
import os . path
import requests
2020-06-03 19:20:32 +02:00
import aiohttp
import asyncio
2022-03-02 22:26:05 +01:00
import psycopg2
from itertools import product
2020-06-03 19:20:32 +02:00
import socket
2021-05-12 16:17:33 +02:00
import matplotlib . pyplot as plt
2021-10-26 13:38:12 +02:00
import pdb
2022-03-03 11:30:59 +01:00
2021-05-12 16:17:33 +02:00
plt . style . use ( ' seaborn ' )
start_time = time . time ( )
2020-06-03 19:20:32 +02:00
client_exceptions = (
aiohttp . ClientResponseError ,
aiohttp . ClientConnectionError ,
aiohttp . ClientConnectorError ,
aiohttp . ClientError ,
asyncio . TimeoutError ,
socket . gaierror ,
)
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-02 22:26:05 +01:00
def get_alive_servers ( self , * args ) :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
fediverse_db , fediverse_db_user = db_config ( )
2021-05-14 13:14:31 +02:00
2022-03-03 11:30:59 +01:00
now = self . now
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
if len ( args ) != 0 :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
self . server = args [ 0 ]
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-02 22:26:05 +01:00
cur . execute ( " select alive, software, users_api, version, first_checked_at, downs from fediverse where server=( %s ) " , ( self . 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 ]
self . software = row [ 1 ]
self . api = row [ 2 ]
self . soft_version = row [ 3 ]
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-02 22:26:05 +01:00
data = requests . get ( ' https:// ' + self . server + self . 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-02 22:26:05 +01:00
self . users = data . json ( ) [ ' usage ' ] [ ' users ' ] [ ' total ' ]
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
if self . users == 0 :
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
self . users = data . json ( ) [ ' usage ' ] [ ' users ' ] [ ' activeHalfyear ' ]
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
if self . software == ' socialhome ' :
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
self . 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-02 22:26:05 +01:00
self . soft_version = data . json ( ) [ ' software ' ] [ ' version ' ]
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
if self . 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-02 22:26:05 +01:00
elif self . 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-02 22:26:05 +01:00
self . users = 0
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
self . 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-02 22:26:05 +01:00
if self . api == ' /api/v1/instance? ' :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
try :
self . users = data . json ( ) [ ' stats ' ] [ ' user_count ' ]
self . soft_version = data . json ( ) [ ' version ' ]
alive = True
except :
self . users = 0
self . 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-02 22:26:05 +01:00
else :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
downs = 0
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
if self . soft_version != " " and self . soft_version is not None :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
print ( f ' \n ** Server { self . server } ( { self . software } { self . 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-02 22:26:05 +01:00
print ( f ' \n ** Server { self . server } ( { self . software } ) is alive! ** ' )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +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-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
conn = None
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
try :
2020-05-17 21:28:03 +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-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
cur = conn . cursor ( )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
cur . execute ( insert_sql , ( self . server , self . users , now , self . software , alive , self . api , self . soft_version , now , now , downs ) )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
if first_checked_at != None :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +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 ) " , ( self . users , now , self . software , alive , self . api , self . soft_version , now , downs , self . server ) )
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
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 ) " , ( self . users , now , self . software , alive , self . api , self . soft_version , now , now , downs , self . server ) )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
cur . execute ( " UPDATE world SET checked= ' t ' where server=( %s ) " , ( self . server , ) )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
conn . commit ( )
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 :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
print ( error )
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
finally :
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
if conn is not None :
2021-10-26 13:38:12 +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
except urllib3 . exceptions . ProtocolError as protoerr :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
print_dead ( self . server )
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-02 22:26:05 +01:00
conn = None
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
try :
2020-05-17 21:28:03 +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-04 19:38:53 +02:00
2022-03-02 22:26:05 +01:00
cur = conn . cursor ( )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
if first_checked_at != None :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
cur . execute ( " UPDATE fediverse SET updated_at=( %s ), alive=( %s ), first_checked_at=( %s ), downs=( %s ) where server=( %s ) " , ( now , alive , now , downs , self . server ) )
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
cur . execute ( " UPDATE fediverse SET updated_at=( %s ), alive=( %s ), downs=( %s ) where server=( %s ) " , ( now , alive , downs , self . server ) )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
cur . execute ( " UPDATE world SET checked= ' t ' where server=( %s ) " , ( self . server , ) )
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
conn . commit ( )
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
cur . close ( )
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
print ( error )
2021-10-26 13:38:12 +02:00
2022-03-02 22:26:05 +01:00
finally :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
if conn is not None :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
conn . close ( )
2020-06-03 19:20:32 +02:00
2022-03-02 22:26:05 +01:00
def print_dead ( server ) :
2020-05-17 21:28:03 +02:00
2022-03-02 22:26:05 +01:00
print ( f ' \n Server { server } is dead :-( ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
def set_world_servers_check_to_false ( ) :
2020-05-17 21:28:03 +02:00
2020-06-03 19:20:32 +02:00
############################################################################
# set all world servers's checked column to False
2020-05-17 21:28:03 +02:00
2020-06-03 19:20:32 +02:00
try :
conn = None
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 ( )
cur . execute ( " UPDATE world SET checked= ' f ' " )
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
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
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
###############################################################################
# main
2020-08-11 20:07:10 +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
set_start_method ( " spawn " )
2020-05-19 23:33:55 +02: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
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 ( )
2021-05-12 16:17:33 +02:00
###########################################################################
# multiprocessing!
2022-03-02 22:26:05 +01:00
with get_context ( " spawn " ) . Pool ( processes = 32 ) as pool :
res = pool . starmap ( getservers . get_alive_servers , product ( alive_servers ) )
pool . close ( )
pool . join ( )
2021-05-12 16:17:33 +02:00
elif sys . argv [ 1 ] == ' --mono ' :
now = datetime . now ( )
mastodon , mastodon_hostname = mastodon ( )
fediverse_db , fediverse_db_user = db_config ( )
total_servers = 0
2022-03-02 22:26:05 +01:00
2021-05-12 16:17:33 +02:00
total_users = 0
set_world_servers_check_to_false ( )
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 ( )
2021-05-12 16:17:33 +02:00
i = 0
while i < len ( alive_servers ) :
2022-03-02 22:26:05 +01:00
getservers . server = alive_servers [ i ]
getservers . get_alive_servers ( )
2021-05-12 16:17:33 +02:00
i + = 1
else :
usage ( )
###########################################################################
# get current total servers and users, get users from every software
2022-03-02 22:26:05 +01:00
now = datetime . now ( )
2021-05-12 16:17:33 +02: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 = [ ]
try :
conn = None
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 " )
2021-05-12 16:17:33 +02:00
cur = conn . cursor ( )
cur . execute ( gettotals_sql )
row = cur . fetchone ( )
total_servers = row [ 0 ]
total_users = row [ 1 ]
cur . execute ( get_soft_totals_sql )
rows = cur . fetchall ( )
for row in rows :
soft_total_project . append ( row [ 0 ] )
soft_total_users . append ( row [ 1 ] )
soft_total_servers . append ( row [ 2 ] )
cur . close ( )
except ( Exception , psycopg2 . DatabaseError ) as error :
print ( error )
finally :
if conn is not None :
conn . close ( )
###########################################################################
# get last check values and write current total ones
select_sql = " select total_servers, total_users from totals order by datetime desc limit 1 "
insert_sql = " INSERT INTO totals(datetime, total_servers, total_users) VALUES( %s , %s , %s ) "
try :
conn = None
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 " )
2021-05-12 16:17:33 +02:00
cur = conn . cursor ( )
cur . execute ( select_sql )
row = cur . fetchone ( )
2021-05-14 13:14:31 +02:00
if row is not None :
2021-05-12 16:17:33 +02:00
servers_before = row [ 0 ]
users_before = row [ 1 ]
else :
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 ) "
2020-05-19 23:33:55 +02:00
2020-06-03 19:20:32 +02:00
conn = None
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
try :
2020-05-19 23:33:55 +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-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
cur = conn . cursor ( )
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
cur . execute ( insert_sql , ( now , evo_servers , evo_users ) )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
conn . commit ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
cur . close ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
print ( error )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
finally :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
if conn is not None :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
conn . close ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
##############################################################################
# get world's last update datetime
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
conn = None
try :
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 " )
2021-05-12 16:17:33 +02:00
cur = conn . cursor ( )
cur . execute ( " select updated_at from world order by updated_at desc limit 1 " )
row = cur . fetchone ( )
last_update = row [ 0 ]
last_update = last_update . strftime ( ' % m/ %d / % Y, % H: % M: % S ' )
cur . close ( )
except ( Exception , psycopg2 . DatabaseError ) as error :
print ( error )
finally :
if conn is not None :
conn . close ( )
##############################################################################
# get max servers and users
2020-05-17 21:28:03 +02:00
2020-06-03 19:20:32 +02:00
conn = None
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
try :
2020-05-17 21:28:03 +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-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
cur = conn . cursor ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
cur . execute ( " select MAX(total_servers) from totals " )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
row = cur . fetchone ( )
2020-05-17 21:28:03 +02:00
2021-05-14 13:14:31 +02:00
if row is not None :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
max_servers = row [ 0 ]
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
else :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
max_servers = 0
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
cur . execute ( " select MAX(total_users) from totals " )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
row = cur . fetchone ( )
2020-05-17 21:28:03 +02:00
2021-05-14 13:14:31 +02:00
if row is not None :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
max_users = row [ 0 ]
else :
max_users = 0
cur . close ( )
except ( Exception , psycopg2 . DatabaseError ) as error :
print ( error )
finally :
if conn is not None :
conn . close ( )
###############################################################################
# get plots
servers_plots = [ ]
users_plots = [ ]
2020-05-17 21:28:03 +02:00
2020-06-03 19:20:32 +02:00
conn = None
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
try :
2020-05-17 21:28:03 +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-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
cur = conn . cursor ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
cur . execute ( " select total_servers, total_users from totals order by datetime desc limit 14 " )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
rows = cur . fetchall ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
for row in rows :
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
servers_plots . append ( row [ 0 ] )
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
users_plots . append ( row [ 1 ] )
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
cur . close ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
except ( Exception , psycopg2 . DatabaseError ) as error :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
print ( error )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
finally :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
if conn is not None :
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
conn . close ( )
2020-06-03 19:20:32 +02:00
2021-05-12 16:17:33 +02:00
###############################################################################
# generate graphs
2020-06-03 19:20:32 +02:00
2021-05-14 13:14:31 +02: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 ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02: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
2021-05-14 13:14:31 +02:00
plt . title ( ' fediverse: total alive servers (max: ' + str ( f " { max_servers : , } " + ' ) ' ) , loc = ' right ' , color = ' blue ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
plt . xlabel ( ' Last seven days ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
plt . ylabel ( ' fediverse alive servers ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02: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
2021-05-12 16:17:33 +02:00
plt . savefig ( ' servers.png ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
plt . close ( )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02: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-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02: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-05-17 21:28:03 +02:00
2021-05-14 13:14:31 +02:00
plt . title ( ' fediverse: total registered users (max: ' + str ( f " { max_users : , } " + ' ) ' ) , loc = ' right ' , color = ' royalblue ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02: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
2021-05-12 16:17:33 +02:00
plt . xlabel ( ' Last seven days ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
plt . ylabel ( ' Registered users ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
plt . savefig ( ' users.png ' )
2020-05-17 21:28:03 +02:00
2021-05-12 16:17:33 +02:00
plt . close ( )
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
###############################################################################
# T O O T !
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
toot_text = " #fediverse alive servers stats " + " \n "
toot_text + = " \n "
if evo_servers > = 0 :
toot_text + = " alive servers: " + str ( f " { total_servers : , } " ) + " (+ " + str ( f " { evo_servers : , } " ) + " ) \n "
toot_text + = " max: " + str ( f " { max_servers : , } " ) + " \n "
elif evo_servers < 0 :
toot_text + = " alive servers: " + str ( f " { total_servers : , } " ) + " ( " + str ( f " { evo_servers : , } " ) + " ) \n "
toot_text + = " max: " + str ( f " { max_servers : , } " ) + " \n "
if evo_users > = 0 :
toot_text + = " total users: " + str ( f " { total_users : , } " ) + " (+ " + str ( f " { evo_users : , } " ) + " ) \n "
toot_text + = " max: " + str ( f " { max_users : , } " ) + " \n "
elif evo_users < 0 :
toot_text + = " total users: " + str ( f " { total_users : , } " ) + " ( " + str ( f " { evo_users : , } " ) + " ) \n "
toot_text + = " max: " + str ( f " { max_users : , } " ) + " \n "
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
toot_text + = " \n "
2021-05-14 13:14:31 +02:00
toot_text + = " top ten (soft users servers): " + " \n "
2021-05-12 16:17:33 +02:00
toot_text + = " \n "
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
i = 0
while i < 10 :
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
project_soft = soft_total_project [ i ]
project_users = soft_total_users [ i ]
project_servers = soft_total_servers [ i ]
len_pr_soft = len ( project_soft )
2020-05-19 23:33:55 +02:00
2021-10-26 13:38:12 +02:00
toot_text + = f " : { project_soft } : { project_users : , } { project_servers : , } \n "
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
i + = 1
2020-05-19 23:33:55 +02:00
2021-05-12 16:17:33 +02:00
print ( " Tooting... " )
print ( toot_text )
2020-05-19 23:33:55 +02:00
2021-10-26 13:38:12 +02:00
servers_image_id = mastodon . media_post ( ' servers.png ' , " image/png " , description = ' servers graph ' ) . id
2021-05-12 16:17:33 +02:00
2021-10-26 13:38:12 +02: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-03 11:30:59 +01:00
mastodon . status_post ( toot_text , in_reply_to_id = None , media_ids = { servers_image_id , users_image_id } )