You know how many servers are federated with your Pleroma server but you don't know much about them. What software are they running? How many users? Are they still alive? These Python scripts will help you to get all that information and much more! https://libretux.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1440 lines
48 KiB

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import time
  4. start_time = time.time()
  5. from six.moves import urllib
  6. from datetime import datetime
  7. import pytz
  8. from subprocess import call
  9. from mastodon import Mastodon
  10. import threading
  11. import os
  12. import json
  13. import signal
  14. import sys
  15. import os.path
  16. import requests
  17. import operator
  18. import calendar
  19. import psycopg2
  20. from importlib import reload
  21. import multiprocessing
  22. from itertools import product
  23. from decimal import *
  24. getcontext().prec = 2
  25. def is_json(myjson):
  26. try:
  27. json_object = json.loads(myjson)
  28. except ValueError as e:
  29. return False
  30. return True
  31. def act_error(error_table, insert_query, federated_server, now):
  32. conn = None
  33. try:
  34. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  35. cur = conn.cursor()
  36. cur.execute(insert_query, (federated_server, now, now, ""))
  37. cur.execute("SELECT added_at FROM " + error_table + " where server=(%s)", (federated_server,))
  38. row = cur.fetchone()
  39. delta = now-row[0]
  40. cur.execute("UPDATE " + error_table + " SET updated_at=(%s), days=(%s) where server=(%s)", (now, delta, federated_server))
  41. conn.commit()
  42. cur.close()
  43. except (Exception, psycopg2.DatabaseError) as error:
  44. print(error)
  45. finally:
  46. if conn is not None:
  47. conn.close()
  48. def get_platform_users(table, platform):
  49. conn = None
  50. try:
  51. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  52. cur = conn.cursor()
  53. cur.execute("select sum(users)from " + table + " where software=(%s)", (platform,))
  54. row = cur.fetchone()
  55. if row[0] != None:
  56. platform_users = row[0]
  57. else:
  58. platform_users = 0
  59. cur.close()
  60. return platform_users
  61. except (Exception, psycopg2.DatabaseError) as error:
  62. print(error)
  63. finally:
  64. if conn is not None:
  65. conn.close()
  66. def get_platform_servers(table, platform):
  67. conn = None
  68. try:
  69. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  70. cur = conn.cursor()
  71. cur.execute("select count(server) from " + table + " where software=(%s)", (platform,))
  72. row = cur.fetchone()
  73. if row != None:
  74. platform_servers = row[0]
  75. else:
  76. platform_servers = 0
  77. cur.close()
  78. return platform_servers
  79. except (Exception, psycopg2.DatabaseError) as error:
  80. print(error)
  81. finally:
  82. if conn is not None:
  83. conn.close()
  84. def get_error_servers(table):
  85. global now
  86. now = str(now).replace("+01:00","")
  87. conn = None
  88. try:
  89. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  90. cur = conn.cursor()
  91. cur.execute("select count(server) from " + table + " where updated_at=(%s)", (now,))
  92. row = cur.fetchone()
  93. if row != None:
  94. error_servers = row[0]
  95. else:
  96. error_servers = 0
  97. cur.close()
  98. return error_servers
  99. except (Exception, psycopg2.DatabaseError) as error:
  100. print(error)
  101. finally:
  102. if conn is not None:
  103. conn.close()
  104. def getserver(server):
  105. global sslerror
  106. global connectionerror
  107. global timeouterror
  108. global mastodont
  109. global pleroma
  110. global gnusocial
  111. global zap
  112. global plume
  113. global hubzilla
  114. global misskey
  115. global prismo
  116. global osada
  117. global groundpolis
  118. global ganggo
  119. global squs
  120. global peertube
  121. global friendica
  122. global pixelfed
  123. global writefreely
  124. global ravenvale
  125. global others
  126. global noresponse
  127. global pl_users
  128. global pl_users_total
  129. global mast_users
  130. global mast_users_total
  131. global gs_users
  132. global gs_users_total
  133. global zap_users
  134. global zap_users_total
  135. global plume_users
  136. global plume_users_total
  137. global hubzilla_users
  138. global hubzilla_users_total
  139. global misskey_users
  140. global misskey_users_total
  141. global prismo_users
  142. global prismo_users_total
  143. global osada_users
  144. global osada_users_total
  145. global gpolis_users
  146. global gpolis_users_total
  147. global ggg_users
  148. global ggg_users_total
  149. global squs_users
  150. global squs_users_total
  151. global peertube_users
  152. global peertube_users_total
  153. global friendica_users
  154. global friendica_users_total
  155. global pixelfed_users
  156. global pixelfed_users_total
  157. global writefreely_users
  158. global writefreely_users_total
  159. global ravenvale_users
  160. global ravenvale_users_total
  161. global total_users
  162. global total_servers
  163. global visited
  164. global server_soft
  165. global soft_version
  166. check_peertube = False
  167. check_zap = False
  168. check_plume = False
  169. check_hubzilla = False
  170. check_misskey = False
  171. check_prismo = False
  172. check_osada = False
  173. check_groundpolis = False
  174. check_ganggo = False
  175. check_squs = False
  176. check_gnusocial = False
  177. check_friendica = False
  178. check_pixelfed = False
  179. check_writefreely = False
  180. check_raven = False
  181. check_gnusocial2 = False
  182. users = 0
  183. instances = 0
  184. server_posts = 0
  185. server_soft = ""
  186. try:
  187. res = requests.get('https://' + server + '/api/v1/instance?',timeout=3)
  188. res_friendica = requests.get('https://' + server + '/nodeinfo/2.0?',timeout=3)
  189. check_pix = "compatible; Pixelfed" in res.text
  190. check_ravenvale = "ravenvale" in res.text
  191. check_friendica = "friendica" in res_friendica.text
  192. if check_friendica == False:
  193. check_friendica = "Friendica" in res_friendica.text
  194. if (res.ok) and check_pix == False and check_ravenvale == False and check_friendica == False:
  195. if res.json()['stats']['user_count'] != "":
  196. instances = res.json()['stats']['domain_count']
  197. nodeinfo = requests.get('https://' + server + '/nodeinfo/2.0.json?',timeout=3)
  198. check_pleroma = "pleroma" in nodeinfo.text.lower()
  199. if nodeinfo.status_code == 200 and check_pleroma == True:
  200. print("Pleroma Server")
  201. pl_users = nodeinfo.json()['usage']['users']['total']
  202. pl_users_total = pl_users_total + pl_users
  203. users = pl_users
  204. server_posts = res.json()['stats']['status_count']
  205. soft_version = nodeinfo.json()['software']['version']
  206. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  207. server_soft = "Pleroma"
  208. print(server, pl_users, instances, server_posts)
  209. print("\n")
  210. else:
  211. print("Mastodon Server")
  212. server_soft = "Mastodon"
  213. mast_users = res.json()['stats']['user_count']
  214. if mast_users != None:
  215. mast_users_total = mast_users_total + mast_users
  216. users = mast_users
  217. server_posts = res.json()['stats']['status_count']
  218. soft_version = res.json()['version']
  219. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  220. print(server, soft_version, mast_users, instances, server_posts)
  221. print("\n")
  222. insert_query = """INSERT INTO federation(server, users, federated_servers, posts, updated_at, software, version)
  223. VALUES(%s,%s,%s,%s,%s,%s,%s) ON CONFLICT DO NOTHING"""
  224. conn = None
  225. try:
  226. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  227. cur = conn.cursor()
  228. cur.execute(insert_query, (server, users, instances, server_posts, now, server_soft, soft_version))
  229. cur.execute("UPDATE federation SET users=(%s), federated_servers=(%s), posts=(%s), updated_at=(%s), software=(%s), version=(%s) where server=(%s)",
  230. (users, instances, server_posts, now, server_soft, soft_version, server))
  231. conn.commit()
  232. cur.close()
  233. except (Exception, psycopg2.DatabaseError) as error:
  234. print(error)
  235. finally:
  236. if conn is not None:
  237. conn.close()
  238. return
  239. except KeyError as e:
  240. print(server + "** Keyerror!: ")
  241. print("Keyerror " + str(e))
  242. print("\n")
  243. error_table = "others_servers"
  244. federated_server = server
  245. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING"
  246. act_error(error_table, insert_query, federated_server, now)
  247. return
  248. except ValueError as verr:
  249. print("Server " + server + " : " + str(verr))
  250. print("Others servers")
  251. print("\n")
  252. return
  253. except requests.exceptions.SSLError as errssl:
  254. print(server + " " + str(errssl))
  255. print("\n")
  256. error_table = "sslerror_servers"
  257. federated_server = server
  258. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING"
  259. act_error(error_table, insert_query, federated_server, now)
  260. return
  261. except requests.exceptions.HTTPError as errh:
  262. print("2 - Http Error:",errh)
  263. return
  264. except requests.exceptions.ConnectionError as errc:
  265. print(server + " ** connection error: ")
  266. print("\n")
  267. error_table = "connerror_servers"
  268. federated_server = server
  269. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s, %s) ON CONFLICT DO NOTHING"
  270. act_error(error_table, insert_query, federated_server, now)
  271. return
  272. except requests.exceptions.Timeout as errt:
  273. print(server + " ** timeout error")
  274. print("\n")
  275. error_table = "timeouterror_servers"
  276. federated_server = server
  277. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING"
  278. act_error(error_table, insert_query, federated_server, now)
  279. return
  280. except requests.exceptions.RequestException as err:
  281. print("5 - OOps: Something Else",err)
  282. else:
  283. try:
  284. soft = ""
  285. others_nodeinfo = requests.get('https://' + server + '/nodeinfo/2.0?',timeout=3)
  286. gs_nodeinfo = requests.get('https://' + server + '/main/nodeinfo/2.0?',timeout=3)
  287. nodeinfo = requests.get('https://' + server + '/nodeinfo/2.0.json?',timeout=3)
  288. statusnet = requests.get('https://' + server + '/api/statusnet/config?',timeout=3)
  289. px_nodeinfo = requests.get('https://' + server + '/api/nodeinfo/2.0.json?',timeout=3)
  290. wf_nodeinfo = requests.get('https://' + server + '/api/nodeinfo?',timeout=3)
  291. try:
  292. if is_json(nodeinfo.text) == True:
  293. if nodeinfo.json() != None:
  294. soft = nodeinfo.json()['software']['name']
  295. if soft == "peertube":
  296. check_peertube = True
  297. elif soft == "prismo":
  298. check_prismo = True
  299. elif soft == "zap":
  300. check_zap = True
  301. elif soft == "osada":
  302. check_osada = True
  303. elif soft == "ravenvale":
  304. check_raven = True
  305. if is_json(others_nodeinfo.text) == True:
  306. soft = others_nodeinfo.json()['software']['name']
  307. if soft == "plume":
  308. check_plume = True
  309. elif soft == "hubzilla":
  310. check_hubzilla = True
  311. elif soft == "misskey":
  312. check_misskey = True
  313. elif soft == "groundpolis":
  314. check_groundpolis = True
  315. elif soft == "ganggo":
  316. check_ganggo = True
  317. elif soft == "squs":
  318. check_squs = True
  319. elif soft == "friendica" or soft == "Friendica":
  320. check_friendica = True
  321. if is_json(wf_nodeinfo.text) == True and soft == "":
  322. if wf_nodeinfo.json().get('error') != None and wf_nodeinfo.json().get('status') == None:
  323. soft = wf_nodeinfo.json()['software']['name']
  324. if soft == "writefreely":
  325. check_writefreely = True
  326. if is_json(gs_nodeinfo.text) == True:
  327. soft = gs_nodeinfo.json()['software']['name']
  328. if soft == "gnusocial":
  329. check_gnusocial = True
  330. if is_json(statusnet.text) == True and soft == "":
  331. if soft != "zap" and soft != "osada":
  332. soft = statusnet.json()['site']['friendica']['FRIENDICA_PLATFORM']
  333. if soft == "Friendica":
  334. check_friendica = True
  335. if is_json(px_nodeinfo.text) == True and soft == "":
  336. if soft != "Friendica" and soft != "hubzilla":
  337. soft = px_nodeinfo.json()['software']['name']
  338. if soft == "pixelfed":
  339. check_pixelfed = True
  340. if soft == "gnusocial":
  341. check_gnusocial2 = True
  342. except :
  343. print("JSONDecodeError")
  344. if check_peertube == False and check_zap == False and check_plume == False and check_hubzilla == False and check_misskey == False and check_prismo == False and check_osada == False and check_groundpolis == False and check_ganggo == False and check_squs == False and check_gnusocial == False and check_friendica == False and check_pixelfed == False and check_writefreely == False and check_raven == False and check_gnusocial2 == False:
  345. print(server + " ** no response")
  346. print("\n")
  347. error_table = "noresponse_servers"
  348. federated_server = server
  349. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING"
  350. act_error(error_table, insert_query, federated_server, now)
  351. api_respon = 0
  352. elif check_peertube == True or check_zap == True or check_plume == True or check_hubzilla == True or check_misskey == True or check_prismo == True or check_osada == True or check_groundpolis == True or check_ganggo == True or check_squs == True or check_gnusocial == True or check_friendica == True or check_pixelfed == True or check_writefreely == True or check_raven == True or check_gnusocial2 == True:
  353. api_respon = 1
  354. if nodeinfo.ok == True and check_peertube == True:
  355. print("Peertube Server")
  356. peertube_users = nodeinfo.json()['usage']['users']['total']
  357. peertube_users_total = peertube_users_total + peertube_users
  358. users = peertube_users
  359. instances = 0
  360. server_posts = nodeinfo.json()['usage']['localPosts']
  361. soft_version = nodeinfo.json()['software']['version']
  362. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  363. server_soft = "Peertube"
  364. print(server, peertube_users, instances, server_posts)
  365. print("\n")
  366. elif nodeinfo.ok == True and check_raven == True:
  367. print("Ravenvale Server")
  368. ravenvale_users = nodeinfo.json()['usage']['users']['total']
  369. ravenvale_users_total = ravenvale_users_total + ravenvale_users
  370. users = ravenvale_users
  371. instances = 0
  372. server_posts = nodeinfo.json()['usage']['localPosts']
  373. soft_version = nodeinfo.json()['software']['version']
  374. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  375. server_soft = "Ravenvale"
  376. print(server, ravenvale_users, instances, server_posts)
  377. print("\n")
  378. elif others_nodeinfo.ok == True and check_zap == True:
  379. print("Zap Server")
  380. zap_users = others_nodeinfo.json()['usage']['users']['total']
  381. zap_users_total = zap_users_total + zap_users
  382. users = zap_users
  383. server_posts = others_nodeinfo.json()['usage']['localPosts']
  384. instances = 0
  385. server_soft = "Zap"
  386. print(server, zap_users, instances, server_posts)
  387. print("\n")
  388. elif others_nodeinfo.ok == True and check_plume == True:
  389. print("Plume Server")
  390. plume_users = others_nodeinfo.json()['usage']['users']['total']
  391. plume_users_total = plume_users_total + plume_users
  392. users = plume_users
  393. server_posts = others_nodeinfo.json()['usage']['localPosts']
  394. soft_version = others_nodeinfo.json()['software']['version']
  395. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  396. instances = 0
  397. server_soft = "Plume"
  398. print(server, plume_users, instances, server_posts)
  399. print("\n")
  400. elif others_nodeinfo.ok == True and check_hubzilla == True:
  401. print("Hubzilla Server")
  402. hubzilla_users = others_nodeinfo.json()['usage']['users']['total']
  403. hubzilla_users_total = hubzilla_users_total + hubzilla_users
  404. users = hubzilla_users
  405. server_posts = others_nodeinfo.json()['usage']['localPosts']
  406. soft_version = others_nodeinfo.json()['software']['version']
  407. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  408. instances = 0
  409. server_soft = "Hubzilla"
  410. print(server, hubzilla_users, instances, server_posts)
  411. print("\n")
  412. elif others_nodeinfo.ok == True and check_misskey == True:
  413. print("Misskey Server")
  414. misskey_users = 0
  415. misskey_users_total = misskey_users_total + misskey_users
  416. users = misskey_users
  417. server_posts = 0
  418. instances = 0
  419. server_soft = "Misskey"
  420. print(server, misskey_users, instances, server_posts)
  421. print("\n")
  422. elif others_nodeinfo.ok == True and check_prismo == True:
  423. print("Prismo Server")
  424. prismo_users = others_nodeinfo.json()['usage']['users']['total']
  425. prismo_users_total = prismo_users_total + prismo_users
  426. users = prismo_users
  427. server_posts = others_nodeinfo.json()['usage']['localPosts']
  428. soft_version = others_nodeinfo.json()['software']['version']
  429. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  430. instances = 0
  431. server_soft = "Prismo"
  432. print(server, prismo_users, instances, server_posts)
  433. print("\n")
  434. elif others_nodeinfo.ok == True and check_osada == True:
  435. print("Osada Server")
  436. osada_users = others_nodeinfo.json()['usage']['users']['total']
  437. osada_users_total = osada_users_total + osada_users
  438. users = osada_users
  439. server_posts = others_nodeinfo.json()['usage']['localPosts']
  440. instances = 0
  441. server_soft = "Osada"
  442. print(server, osada_users, instances, server_posts)
  443. print("\n")
  444. elif others_nodeinfo.ok == True and check_groundpolis == True:
  445. print("Groundpolis Server")
  446. gpolis_users = others_nodeinfo.json()['usage']['users']['total']
  447. gpolis_users_total = gpolis_users_total + gpolis_users
  448. users = gpolis_users
  449. server_posts = others_nodeinfo.json()['usage']['localPosts']
  450. instances = 0
  451. server_soft = "Groundpolis"
  452. print(server, gpolis_users, instances, server_posts)
  453. print("\n")
  454. elif others_nodeinfo.ok == True and check_ganggo == True:
  455. print("Ganggo Server")
  456. ggg_users = others_nodeinfo.json()['usage']['users']['total']
  457. ggg_users_total = ggg_users_total + ggg_users
  458. users = ggg_users
  459. server_posts = others_nodeinfo.json()['usage']['localPosts']
  460. instances = 0
  461. server_soft = "Ganggo"
  462. print(server, ggg_users, instances, server_posts)
  463. print("\n")
  464. elif others_nodeinfo.ok == True and check_squs == True:
  465. print("Squs Server")
  466. squs_users = others_nodeinfo.json()['usage']['users']['total']
  467. squs_users_total = squs_users_total + squs_users
  468. users = squs_users
  469. server_posts = others_nodeinfo.json()['usage']['localPosts']
  470. instances = 0
  471. server_soft = "Squs"
  472. print(server, squs_users, instances, server_posts)
  473. print("\n")
  474. elif others_nodeinfo.ok == True and check_friendica == True:
  475. print("Friendica Server")
  476. if others_nodeinfo.json()['usage'] != []:
  477. friendica_users = others_nodeinfo.json()['usage']['users']['total']
  478. server_posts = others_nodeinfo.json()['usage']['localPosts']
  479. else:
  480. friendica_users = 0
  481. server_posts = 0
  482. friendica_users_total = friendica_users_total + friendica_users
  483. users = friendica_users
  484. instances = 0
  485. soft_version = others_nodeinfo.json()['software']['version']
  486. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  487. server_soft = "Friendica"
  488. print(server, friendica_users, instances, server_posts)
  489. print("\n")
  490. check_friendica = False
  491. elif gs_nodeinfo.ok == True and check_gnusocial == True:
  492. print("GNU Social Server")
  493. gs_users = gs_nodeinfo.json()['usage']['users']['total']
  494. if gs_users == 0:
  495. gs_users = gs_nodeinfo.json()['usage']['users']['activeHalfyear']
  496. gs_users_total = gs_users_total + gs_users
  497. users = gs_users
  498. server_posts = gs_nodeinfo.json()['usage']['localPosts']
  499. instances = 0
  500. server_soft = "GNU Social"
  501. soft_version = gs_nodeinfo.json()['software']['version']
  502. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  503. print(server, gs_users, instances, server_posts)
  504. print("\n")
  505. elif statusnet.ok == True and check_friendica == True: #statusnet.json()['site']['friendica']['FRIENDICA_PLATFORM'] == "Friendica":
  506. print("Friendica Server")
  507. friendica_users = 0
  508. friendica_users_total = friendica_users_total + friendica_users
  509. users = friendica_users
  510. instances = 0
  511. server_posts = 0
  512. soft_version = statusnet.json()['site']['friendica']['FRIENDICA_VERSION']
  513. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  514. server_soft = "Friendica"
  515. print(server, friendica_users, instances, server_posts)
  516. print("\n")
  517. elif px_nodeinfo.ok == True and check_pixelfed == True:
  518. print("Pixelfed Server")
  519. pixelfed_users = px_nodeinfo.json()['usage']['users']['total']
  520. pixelfed_users_total = pixelfed_users_total + pixelfed_users
  521. users = pixelfed_users
  522. instances = 0
  523. server_posts = px_nodeinfo.json()['usage']['localPosts']
  524. soft_version = px_nodeinfo.json()['software']['version']
  525. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  526. server_soft = "Pixelfed"
  527. print(server, pixelfed_users, instances, server_posts)
  528. print("\n")
  529. elif px_nodeinfo.ok == True and check_gnusocial2 == True:
  530. print("GNU Social 2.x Server")
  531. gs_users = px_nodeinfo.json()['usage']['users']['total']
  532. if gs_users == 0:
  533. gs_users = px_nodeinfo.json()['usage']['users']['activeHalfyear']
  534. gs_users_total = gs_users_total + gs_users
  535. users = gs_users
  536. instances = 0
  537. server_posts = px_nodeinfo.json()['usage']['localPosts']
  538. soft_version = px_nodeinfo.json()['software']['version']
  539. soft_version = (soft_version[:37] + '... ') if len(soft_version) > 37 else soft_version
  540. server_soft = "GNU Social"
  541. print(server, gs_users, instances, server_posts)
  542. print("\n")
  543. elif wf_nodeinfo.ok == True and check_writefreely == True:
  544. print("WriteFreely Server")
  545. writefreely_users = wf_nodeinfo.json()['usage']['users']['total']
  546. writefreely_users_total = writefreely_users_total + writefreely_users
  547. users = writefreely_users
  548. instances = 0
  549. server_posts = wf_nodeinfo.json()['usage']['localPosts']
  550. server_soft = "WriteFreely"
  551. print(server, writefreely_users, instances, server_posts)
  552. print("\n")
  553. else:
  554. print(server + " ** no response")
  555. error_table = "noresponse_servers"
  556. federated_server = server
  557. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING"
  558. act_error(error_table, insert_query, federated_server, now)
  559. api_respon = 0
  560. if api_respon == 1 and others_nodeinfo.ok or gs_nodeinfo.ok or nodeinfo.ok or statusnet.ok or px_nodeinfo.ok or wf_nodeinfo.ok:
  561. insert_query = """INSERT INTO federation(server, users, federated_servers, posts, updated_at, software, version)
  562. VALUES(%s,%s,%s,%s,%s,%s,%s) ON CONFLICT DO NOTHING"""
  563. conn = None
  564. try:
  565. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  566. cur = conn.cursor()
  567. cur.execute(insert_query, (server, users, instances, server_posts, now, server_soft, soft_version))
  568. cur.execute("UPDATE federation SET users=(%s), federated_servers=(%s), posts=(%s), updated_at=(%s), software=(%s), version=(%s) where server=(%s)",
  569. (users, instances, server_posts, now, server_soft, soft_version, server))
  570. conn.commit()
  571. cur.close()
  572. return
  573. except (Exception, psycopg2.DatabaseError) as error:
  574. print(error)
  575. return
  576. finally:
  577. if conn is not None:
  578. conn.close()
  579. return
  580. except KeyError as e:
  581. print(server + "** Keyerror!")
  582. print("Keyerror " + str(e))
  583. print("\n")
  584. error_table = "others_servers"
  585. federated_server = server
  586. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING"
  587. act_error(error_table, insert_query, federated_server, now)
  588. return
  589. except ValueError as verr:
  590. print("ValueError!")
  591. print(verr)
  592. print("Server (ValeuError): " + server)
  593. print("Other servers")
  594. print("\n")
  595. return
  596. except requests.exceptions.ConnectionError as errc:
  597. print(server + " ** connection error")
  598. print("\n")
  599. error_table = "connerror_servers"
  600. federated_server = server
  601. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s, %s) ON CONFLICT DO NOTHING"
  602. act_error(error_table, insert_query, federated_server, now)
  603. return
  604. ########################################################################################
  605. except requests.exceptions.Timeout as errt:
  606. print(server + " ** timeout error")
  607. print("\n")
  608. error_table = "timeouterror_servers"
  609. federated_server = server
  610. insert_query = "INSERT INTO " + error_table + "(server, added_at, updated_at, days) VALUES(%s,%s,%s,%s) ON CONFLICT DO NOTHING"
  611. act_error(error_table, insert_query, federated_server, now)
  612. return
  613. ###############################################################################
  614. # INITIALISATION
  615. ###############################################################################
  616. # Returns the parameter from the specified file
  617. def get_parameter( parameter, file_path ):
  618. # Check if secrets file exists
  619. if not os.path.isfile(file_path):
  620. print("File %s not found, exiting."%file_path)
  621. sys.exit(0)
  622. # Find parameter in file
  623. with open( file_path ) as f:
  624. for line in f:
  625. if line.startswith( parameter ):
  626. return line.replace(parameter + ":", "").strip()
  627. # Cannot find parameter, exit
  628. print(file_path + " Missing parameter %s "%parameter)
  629. sys.exit(0)
  630. # Load secrets from secrets file
  631. secrets_filepath = "secrets/secrets.txt"
  632. uc_client_id = get_parameter("uc_client_id", secrets_filepath)
  633. uc_client_secret = get_parameter("uc_client_secret", secrets_filepath)
  634. uc_access_token = get_parameter("uc_access_token", secrets_filepath)
  635. # Load configuration from config file
  636. config_filepath = "config.txt"
  637. pleroma_hostname = get_parameter("pleroma_hostname", config_filepath) # E.g., pleroma.site
  638. pleroma_db = get_parameter("pleroma_db", config_filepath) # E.g., pleroma_prod
  639. pleroma_db_user = get_parameter("pleroma_db_user", config_filepath) # E.g., pleroma
  640. fediverse_db = get_parameter("fediverse_db", config_filepath) # E.g., pleroma_federation
  641. fediverse_db_user = get_parameter("fediverse_db_user", config_filepath) # E.g., pleroma
  642. multiprocessing_processes = get_parameter("multiprocessing_processes", config_filepath) # E.g., cpu cores number)
  643. # Initialise Mastodon API
  644. mastodon = Mastodon(
  645. client_id = uc_client_id,
  646. client_secret = uc_client_secret,
  647. access_token = uc_access_token,
  648. api_base_url = 'https://' + pleroma_hostname,
  649. )
  650. # Initialise access headers
  651. headers={ 'Authorization': 'Bearer %s'%uc_access_token }
  652. ###############################################################################
  653. # get rejected instances from API to avoid getting information from them
  654. ###############################################################################
  655. res = requests.get('https://' + pleroma_hostname + '/nodeinfo/2.0.json?')
  656. rejected = res.json()['metadata']['federation']['mrf_simple']['reject']
  657. ###############################################################################
  658. # federated servers with pleroma host - @spla@pleroma.cat - 6.9.2019
  659. # SELECT distinct split_part(nickname, '@', 2) FROM users;
  660. ###########################################################################################
  661. sslerror = 0
  662. connectionerror = 0
  663. timeouterror= 0
  664. mastodont = 0
  665. pleroma = 0
  666. gnusocial = 0
  667. zap = 0
  668. plume = 0
  669. hubzilla = 0
  670. misskey = 0
  671. prismo = 0
  672. osada = 0
  673. groundpolis = 0
  674. ganggo = 0
  675. squs = 0
  676. peertube = 0
  677. friendica = 0
  678. pixelfed = 0
  679. others = 0
  680. noresponse = 0
  681. pl_users = 0
  682. pl_users_total = 0
  683. mast_users = 0
  684. mast_users_total = 0
  685. gs_users = 0
  686. gs_users_total = 0
  687. zap_users = 0
  688. zap_users_total = 0
  689. plume_users = 0
  690. plume_users_total = 0
  691. hubzilla_users = 0
  692. hubzilla_users_total = 0
  693. misskey_users = 0
  694. misskey_users_total = 0
  695. prismo_users = 0
  696. prismo_users_total = 0
  697. osada_users = 0
  698. osada_users_total = 0
  699. gpolis_users = 0
  700. gpolis_users_total = 0
  701. ggg_users = 0
  702. ggg_users_total = 0
  703. squs_users = 0
  704. squs_users_total = 0
  705. peertube_users = 0
  706. peertube_users_total = 0
  707. friendica_users = 0
  708. friendica_users_total = 0
  709. pixelfed_users = 0
  710. pixelfed_users_total = 0
  711. total_users = 0
  712. total_servers = 0
  713. visited = 0
  714. server_soft = ""
  715. tz = pytz.timezone('Europe/Madrid')
  716. now = datetime.now(tz)
  717. try:
  718. conn = None
  719. conn = psycopg2.connect(database = pleroma_db, user = pleroma_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  720. cur = conn.cursor()
  721. ### get federated servers from Pleroma database
  722. cur.execute("SELECT distinct split_part(nickname, '@', 2) FROM users")
  723. federated_servers = []
  724. for row in cur:
  725. if row[0] != None:
  726. federated_servers.append(row[0]) ## save them to federated_servers array
  727. cur.close()
  728. except (Exception, psycopg2.DatabaseError) as error:
  729. print(error)
  730. finally:
  731. if conn is not None:
  732. conn.close()
  733. ###########################################################################
  734. # remove rejected servers from federated_servers array because
  735. # we don't want to collect their stats
  736. ###########################################################################
  737. i = 0
  738. while i < len(rejected):
  739. if rejected[i] in federated_servers:
  740. federated_servers.remove(rejected[i])
  741. i += 1
  742. ###########################################################################
  743. # do multiprocessing
  744. processes_number = int(multiprocessing_processes)
  745. with multiprocessing.Pool(processes=processes_number) as pool:
  746. results = pool.starmap(getserver, product(federated_servers))
  747. print(results)
  748. ###############################################################################################
  749. # get servers with error
  750. table ='others_servers'
  751. others = get_error_servers(table)
  752. table ='connerror_servers'
  753. connectionerror = get_error_servers(table)
  754. table ='noresponse_servers'
  755. noresponse = get_error_servers(table)
  756. table ='sslerror_servers'
  757. sslerror = get_error_servers(table)
  758. table ='timeouterror_servers'
  759. timeouterror = get_error_servers(table)
  760. ################################################################################################
  761. # How many servers of each software
  762. ################################################################################################
  763. table = 'federation'
  764. platform = 'Mastodon'
  765. mastodont = get_platform_servers(table, platform)
  766. platform = 'Pleroma'
  767. pleroma = get_platform_servers(table, platform)
  768. platform = 'Peertube'
  769. peertube = get_platform_servers(table, platform)
  770. platform = 'Friendica'
  771. friendica = get_platform_servers(table, platform)
  772. platform = 'Pixelfed'
  773. pixelfed = get_platform_servers(table, platform)
  774. platform = 'Misskey'
  775. misskey = get_platform_servers(table, platform)
  776. platform = 'Hubzilla'
  777. hubzilla = get_platform_servers(table, platform)
  778. platform = 'GNU Social'
  779. gnusocial = get_platform_servers(table, platform)
  780. platform = 'Plume'
  781. plume = get_platform_servers(table, platform)
  782. platform = 'Zap'
  783. zap = get_platform_servers(table, platform)
  784. platform = 'Osada'
  785. osada = get_platform_servers(table, platform)
  786. platform = 'Prismo'
  787. prismo = get_platform_servers(table, platform)
  788. platform = 'Groundpolis'
  789. groundpolis = get_platform_servers(table, platform)
  790. platform = 'Ravenvale'
  791. ravenvale = get_platform_servers(table, platform)
  792. platform = 'Squs'
  793. squs = get_platform_servers(table, platform)
  794. platform = 'Writefreely'
  795. writefreely = get_platform_servers(table, platform)
  796. platform = 'Ganggo'
  797. ganggo = get_platform_servers(table, platform)
  798. platform = 'Others'
  799. others = get_platform_servers(table, platform)
  800. total_servers = mastodont + pleroma + gnusocial + zap + plume + hubzilla + misskey + prismo + osada + groundpolis + ganggo + squs + peertube + friendica + pixelfed + writefreely + ravenvale + others
  801. visited = len(federated_servers)
  802. ##################################################################################################
  803. # get users of each software and total users
  804. table = 'federation'
  805. platform = 'Mastodon'
  806. mast_users_total = get_platform_users(table, platform)
  807. platform = 'Pleroma'
  808. pl_users_total = get_platform_users(table, platform)
  809. platform = 'Peertube'
  810. peertube_users_total = get_platform_users(table, platform)
  811. platform = 'Friendica'
  812. friendica_users_total = get_platform_users(table, platform)
  813. platform = 'Pixelfed'
  814. pixelfed_users_total = get_platform_users(table, platform)
  815. platform = 'Misskey'
  816. misskey_users_total = get_platform_users(table, platform)
  817. platform = 'Hubzilla'
  818. hubzilla_users_total = get_platform_users(table, platform)
  819. platform = 'GNU Social'
  820. gs_users_total = get_platform_users(table, platform)
  821. platform = 'Plume'
  822. plume_users_total = get_platform_users(table, platform)
  823. platform = 'Zap'
  824. zap_users_total = get_platform_users(table, platform)
  825. platform = 'Osada'
  826. osada_users_total = get_platform_users(table, platform)
  827. platform = 'Prismo'
  828. prismo_users_total = get_platform_users(table, platform)
  829. platform = 'Groundpolis'
  830. gpolis_users_total = get_platform_users(table, platform)
  831. platform = 'Ravenvale'
  832. ravenvale_users_total = get_platform_users(table, platform)
  833. platform = 'Squs'
  834. squs_users_total = get_platform_users(table, platform)
  835. platform = 'Writefreely'
  836. writefreely_users_total = get_platform_users(table, platform)
  837. platform = 'Ganggo'
  838. ggg_users_total = get_platform_users(table, platform)
  839. total_users = mast_users_total + pl_users_total + gs_users_total + zap_users_total + plume_users_total + hubzilla_users_total + misskey_users_total + prismo_users_total
  840. total_users = total_users + osada_users_total + gpolis_users_total + ggg_users_total + squs_users_total + peertube_users_total + friendica_users_total + pixelfed_users_total
  841. total_users = total_users + writefreely_users_total + ravenvale_users_total
  842. ###############################################################################################
  843. # delete from database back on life servers #
  844. ###############################################################################################
  845. conn = None
  846. try:
  847. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  848. cur = conn.cursor()
  849. cur.execute("DELETE from sslerror_servers where updated_at < %s OR updated_at is null", (now,))
  850. cur.execute("DELETE from connerror_servers where updated_at < %s OR updated_at is null", (now,))
  851. cur.execute("DELETE from timeouterror_servers where updated_at < %s OR updated_at is null", (now,))
  852. conn.commit()
  853. cur.close()
  854. except (Exception, psycopg2.DatabaseError) as error:
  855. print(error)
  856. finally:
  857. if conn is not None:
  858. conn.close()
  859. ########################### delete inactive servers from federation table
  860. conn = None
  861. try:
  862. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  863. cur = conn.cursor()
  864. cur.execute("DELETE from federation where updated_at < %s OR updated_at is null", (now,))
  865. conn.commit()
  866. cur.close()
  867. except (Exception, psycopg2.DatabaseError) as error:
  868. print(error)
  869. finally:
  870. if conn is not None:
  871. conn.close()
  872. ################################################################################################
  873. # get last check values
  874. ################################################################################################
  875. select = """select visited, mastodon, others, no_response, ssl_error, timeout_error, connection_error, total_servers, total_users, pleroma, mastodon_users,
  876. pleroma_users, gnusocial, gnusocial_users, zap, zap_users, plume, plume_users, hubzilla, hubzilla_users, misskey, misskey_users, prismo, prismo_users, osada, osada_users,
  877. groundpolis, gpolis_users, ganggo, ganggo_users, squs, squs_users, peertube, peertube_users, friendica, friendica_users, pixelfed, pixelfed_users, writefreely, writefreely_users,
  878. ravenvale, ravenvale_users from federated_servers order by datetime desc limit 1;"""
  879. try:
  880. conn = None
  881. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  882. cur = conn.cursor()
  883. cur.execute(select)
  884. row = cur.fetchone()
  885. visited_before = row[0]
  886. mastodont_before = row[1]
  887. others_before = row[2]
  888. noresponse_before = row[3]
  889. sslerror_before = row[4]
  890. timeout_error_before = row[5]
  891. connerror_before = row[6]
  892. serv_total_before = row[7]
  893. total_users_before = row[8]
  894. pleroma_before = row[9]
  895. mastodon_users_before = row[10]
  896. pleroma_users_before = row[11]
  897. gnusocial_before = row[12]
  898. gnusocial_users_before = row[13]
  899. zap_before = row[14]
  900. zap_users_before = row[15]
  901. plume_before = row[16]
  902. plume_users_before = row[17]
  903. hubzilla_before = row[18]
  904. hubzilla_users_before = row[19]
  905. misskey_before = row[20]
  906. misskey_users_before = row[21]
  907. prismo_before = row[22]
  908. prismo_users_before = row[23]
  909. osada_before = row[24]
  910. osada_users_before = row[25]
  911. groundpolis_before = row[26]
  912. groundpolis_users_before = row[27]
  913. ganggo_before = row[28]
  914. ganggo_users_before = row[29]
  915. squs_before = row[30]
  916. squs_users_before = row[31]
  917. peertube_before = row[32]
  918. peertube_users_before = row[33]
  919. friendica_before = row[34]
  920. friendica_users_before = row[35]
  921. pixelfed_before = row[36]
  922. pixelfed_users_before = row[37]
  923. writefreely_before = row[38]
  924. writefreely_users_before = row[39]
  925. ravenvale_before = row[40]
  926. ravenvale_users_before = row[41]
  927. cur.close()
  928. evo_visited = visited - visited_before
  929. evo_mastodont = mastodont - mastodont_before
  930. evo_others = others - others_before
  931. evo_noresponse = noresponse - noresponse_before
  932. evo_sslerror = sslerror - sslerror_before
  933. evo_timeout_error = timeouterror - timeout_error_before
  934. evo_connerror = connectionerror - connerror_before
  935. evo_serv_total = total_servers - serv_total_before
  936. evo_total_users = total_users - total_users_before
  937. evo_pleroma = pleroma - pleroma_before
  938. evo_mast_users = mast_users_total - mastodon_users_before
  939. evo_pl_users = pl_users_total - pleroma_users_before
  940. evo_gnusocial = gnusocial - gnusocial_before
  941. evo_gs_users = gs_users_total - gnusocial_users_before
  942. evo_zap = zap - zap_before
  943. evo_zap_users = zap_users_total - zap_users_before
  944. evo_plume = plume - plume_before
  945. evo_plume_users = plume_users_total - plume_users_before
  946. evo_hubzilla = hubzilla - hubzilla_before
  947. evo_hub_users = hubzilla_users_total - hubzilla_users_before
  948. evo_misskey = misskey - misskey_before
  949. evo_misskey_users = misskey_users_total - misskey_users_before
  950. evo_prismo = prismo - prismo_before
  951. evo_prismo_users = prismo_users_total - prismo_users_before
  952. evo_osada = osada - osada_before
  953. evo_osada_users = osada_users_total - osada_users_before
  954. evo_groundpolis = groundpolis - groundpolis_before
  955. evo_groundpolis_users = gpolis_users_total - groundpolis_users_before
  956. evo_ganggo = ganggo - ganggo_before
  957. evo_ganggo_users = ggg_users_total - ganggo_users_before
  958. evo_squs = squs - squs_before
  959. evo_squs_users = squs_users_total - squs_users_before
  960. evo_peertube = peertube - peertube_before
  961. evo_peertube_users = peertube_users_total - peertube_users_before
  962. evo_friendica = friendica - friendica_before
  963. evo_friendica_users = friendica_users_total - friendica_users_before
  964. evo_pixelfed = pixelfed - pixelfed_before
  965. evo_pixelfed_users = pixelfed_users_total - pixelfed_users_before
  966. evo_writefreely = writefreely - writefreely_before
  967. evo_writefreely_users = writefreely_users_total - writefreely_users_before
  968. evo_ravenvale = ravenvale - ravenvale_before
  969. evo_ravenvale_users = ravenvale_users_total - ravenvale_users_before
  970. except (Exception, psycopg2.DatabaseError) as error:
  971. print(error)
  972. finally:
  973. if conn is not None:
  974. conn.close()
  975. ################################################################################
  976. # save evolution to evo table
  977. ################################################################################
  978. insert_line = """INSERT INTO evo(datetime, visited, mastodon, others, no_response, ssl_error, timeout_error, connection_error, total_servers, total_users, pleroma, mastodon_users,
  979. pleroma_users, gnusocial, gnusocial_users, zap, zap_users, plume, plume_users, hubzilla, hubzilla_users, misskey, misskey_users, prismo, prismo_users, osada, osada_users,
  980. groundpolis, gpolis_users, ganggo, ganggo_users, squs, squs_users, peertube, peertube_users, friendica, friendica_users, pixelfed, pixelfed_users)
  981. VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) RETURNING datetime;"""
  982. conn = None
  983. try:
  984. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  985. cur = conn.cursor()
  986. cur.execute(insert_line, (now, evo_visited, evo_mastodont, evo_others, evo_noresponse, evo_sslerror, evo_timeout_error, evo_connerror, evo_serv_total, evo_total_users, evo_pleroma, evo_mast_users,
  987. evo_pl_users, evo_gnusocial, evo_gs_users, evo_zap, evo_zap_users, evo_plume, evo_plume_users, evo_hubzilla, evo_hub_users, evo_misskey, evo_misskey_users,
  988. evo_prismo, evo_prismo_users, evo_osada, evo_osada_users, evo_groundpolis, evo_groundpolis_users, evo_ganggo, evo_ganggo_users, evo_squs, evo_squs_users,
  989. evo_peertube, evo_peertube_users, evo_friendica, evo_friendica_users, evo_pixelfed, evo_pixelfed_users))
  990. conn.commit()
  991. cur.close()
  992. except (Exception, psycopg2.DatabaseError) as error:
  993. print(error)
  994. finally:
  995. if conn is not None:
  996. conn.close()
  997. ################################################################################
  998. insert_line = """INSERT INTO federated_servers(datetime, visited, mastodon, others, no_response, ssl_error, timeout_error, connection_error, total_servers, total_users, pleroma, mastodon_users,
  999. pleroma_users, gnusocial, gnusocial_users, zap, zap_users, plume, plume_users, hubzilla, hubzilla_users, misskey, misskey_users, prismo, prismo_users, osada, osada_users,
  1000. groundpolis, gpolis_users, ganggo, ganggo_users, squs, squs_users, peertube, peertube_users, friendica, friendica_users, pixelfed, pixelfed_users) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,
  1001. %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) RETURNING datetime;"""
  1002. conn = None
  1003. try:
  1004. conn = psycopg2.connect(database = fediverse_db, user = fediverse_db_user, password = "", host = "/var/run/postgresql", port = "5432")
  1005. cur = conn.cursor()
  1006. cur.execute(insert_line, (now, visited, mastodont, others, noresponse, sslerror, timeouterror, connectionerror, total_servers, total_users, pleroma, mast_users_total, pl_users_total,
  1007. gnusocial, gs_users_total, zap, zap_users_total, plume, plume_users_total, hubzilla, hubzilla_users_total, misskey, misskey_users_total, prismo, prismo_users_total,
  1008. osada, osada_users_total, groundpolis, gpolis_users_total, ganggo, ggg_users_total, squs, squs_users_total, peertube, peertube_users_total, friendica,
  1009. friendica_users_total, pixelfed, pixelfed_users_total))
  1010. conn.commit()
  1011. cur.close()
  1012. except (Exception, psycopg2.DatabaseError) as error:
  1013. print(error)
  1014. finally:
  1015. if conn is not None:
  1016. conn.close()
  1017. ###############################################################################
  1018. # calc percentages
  1019. ###############################################################################
  1020. print("Percentatges:")
  1021. print("Visited Domains : " + str(visited))
  1022. perc_no_response = round(((noresponse * 100.00) / visited), 2)
  1023. print("No response domains: " + str(noresponse) + " (" + str(perc_no_response) + "%)")
  1024. perc_error_ssl = round(((sslerror * 100.00) / visited), 2)
  1025. print("SSL error: " + str(sslerror) + " (" + str(perc_error_ssl) + "%)")
  1026. perc_error_tout = round(((timeouterror * 100.00) / visited), 2)
  1027. print("TimeOut error: " + str(timeouterror) + " (" + str(perc_error_tout) + "%)")
  1028. perc_error_conn = round(((connectionerror * 100.00) / visited), 2)
  1029. print("Connection error: " + str(connectionerror) + " (" + str(perc_error_conn) + "%)")
  1030. print("The fediverse:" + "\n")
  1031. print("Active servers: " + str(total_servers))
  1032. print("Registered users: " + str(total_users))
  1033. ###############################################################################
  1034. # T O O T !
  1035. ###############################################################################
  1036. toot_text = "#fediverse view from " + pleroma_hostname + " \n"
  1037. toot_text += "\n"
  1038. toot_text += "Domains:" + "\n"
  1039. toot_text += "Visited " + str(visited) + " \n"
  1040. toot_text += "No response " + str(noresponse) + " (" + str(perc_no_response) + "%)" + "\n"
  1041. toot_text += "SSL error " + str(sslerror) + " (" + str(perc_error_ssl) + "%)" + "\n"
  1042. toot_text += "Timeout error " + str(timeouterror) + " (" + str(perc_error_tout) + "%)" + "\n"
  1043. toot_text += "Connection error " + str(connectionerror) + " (" + str(perc_error_conn) + "%)" + "\n"
  1044. toot_text += "\n"
  1045. toot_text += "The fediverse:" + "\n"
  1046. toot_text += "Total active servers: " + str(total_servers) + "\n"
  1047. toot_text += "Mastodon -> " + str(mastodont) + "\n"
  1048. toot_text += "Pleroma -> " + str(pleroma) + "\n"
  1049. toot_text += "Peertube -> " + str(peertube) + "\n"
  1050. toot_text += "Misskey -> " + str(misskey) + "\n"
  1051. toot_text += "Friendica -> " + str(friendica) + "\n"
  1052. toot_text += "Hubzilla -> " + str(hubzilla) + "\n"
  1053. toot_text += "Plume -> " + str(plume) + "\n"
  1054. toot_text += "GNU Social -> " + str(gnusocial) + "\n"
  1055. toot_text += "Pixelfed -> " + str(pixelfed) + "\n"
  1056. toot_text += "Zap -> " + str(zap) + "\n"
  1057. toot_text += "Groundpolis -> " + str(groundpolis) + "\n"
  1058. toot_text += "Prismo -> " + str(prismo) + "\n"
  1059. toot_text += "Osada -> " + str(osada) + "\n"
  1060. toot_text += "Ganggo -> " + str(ganggo) + "\n"
  1061. toot_text += "Squs -> " + str(squs) + "\n"
  1062. toot_text += "Writefreely -> " + str(writefreely) + "\n"
  1063. toot_text += "Ravenvale -> " + str(ravenvale) + "\n"
  1064. toot_text += "\n"
  1065. toot_text += "Total registered users: " + str(total_users) + "\n"
  1066. toot_text += "Mastodon -> " + str(mast_users_total) + "\n"
  1067. toot_text += "Pleroma: -> " + str(pl_users_total) + "\n"
  1068. toot_text += "Peertube -> " + str(peertube_users_total) + "\n"
  1069. toot_text += "Hubzilla -> " + str(hubzilla_users_total) + "\n"
  1070. toot_text += "GNU Social -> " + str(gs_users_total) + "\n"
  1071. toot_text += "Pixelfed -> " + str(pixelfed_users_total) + "\n"
  1072. toot_text += "Prismo -> " + str(prismo_users_total) + "\n"
  1073. toot_text += "Zap -> " + str(zap_users_total) + "\n"
  1074. toot_text += "Plume -> " + str(plume_users_total) + "\n"
  1075. toot_text += "Friendica -> " + str(friendica_users_total) + "\n"
  1076. toot_text += "Misskey -> " + str(misskey_users_total) + "\n"
  1077. toot_text += "Osada -> " + str(osada_users_total) + "\n"
  1078. toot_text += "GroundPolis -> " + str(gpolis_users_total) + "\n"
  1079. toot_text += "Ganggo -> " + str(ggg_users_total) + "\n"
  1080. toot_text += "Squs -> " + str(squs_users_total) + "\n"
  1081. toot_text += "Writefreely -> " + str(writefreely_users_total) + "\n"
  1082. toot_text += "Ravenvale -> " + str(ravenvale_users_total) + "\n"
  1083. toot_text += "\n"
  1084. toot_text += "Execution time: %s segons" % (time.time() - start_time)
  1085. print("Tooting...")
  1086. print(toot_text)
  1087. mastodon.status_post(toot_text, in_reply_to_id=None, )
  1088. print("Tooted succesfully!")