| <?php | |
| // This class adapted from: https://www.if-not-true-then-false.com/2010/php-class-for-coloring-php-command-line-cli-scripts-output-php-output-colorizing-using-bash-shell-colors/ | |
| class Colors { | |
| private static $foreground_colors = array( | |
| 'black'=>'0;30', | |
| 'dark_gray'=>'1;30', | |
| 'blue'=>'0;34', | |
| 'light_blue'=>'1;34', | |
| 'green'=>'0;32', | |
| 'light_green'=>'1;32', | |
| 'cyan'=>'0;36', | |
| 'light_cyan'=>'1;36', | |
| 'red'=>'0;31', | |
| 'light_red'=>'1;31', | |
| 'purple'=>'0;35', | |
| 'light_purple'=>'1;35', | |
| 'brown'=>'0;33', | |
| 'yellow'=>'1;33', | |
| 'light_gray'=>'0;37', | |
| 'white'=>'1;37' | |
| ); | |
| private static $background_colors = array( | |
| 'black'=>'40', | |
| 'red'=>'41', | |
| 'green'=>'42', | |
| 'yellow'=>'43', | |
| 'cyan'=>'44', | |
| 'magenta'=>'45', | |
| 'light_cyan'=>'46', | |
| 'light_gray'=>'47' | |
| ); | |
| // Returns colored string | |
| public static function getColoredString($string, $foreground_color = null, $background_color = 'black') { | |
| // Only colour the string if the user hasn't opted out of colour. | |
| global $colour; | |
| if (!$colour) return $string; | |
| $colored_string = ""; | |
| // Check if given foreground color found | |
| if (isset(self::$foreground_colors[$foreground_color])) { | |
| $colored_string .= "\033[" . self::$foreground_colors[$foreground_color] . "m"; | |
| } | |
| // Check if given background color found | |
| if (isset(self::$background_colors[$background_color])) { | |
| $colored_string .= "\033[" . self::$background_colors[$background_color] . "m"; | |
| } | |
| // Add string and end coloring | |
| $colored_string .= $string . "\033[0m"; | |
| return $colored_string; | |
| } | |
| // Returns all foreground color names | |
| public static function getForegroundColors() { | |
| return array_keys(self::$foreground_colors); | |
| } | |
| // Returns all background color names | |
| public static function getBackgroundColors() { | |
| return array_keys(self::$background_colors); | |
| } | |
| } | |
| function getColoredString($string, $foreground_color = null, $background_color = 'black') { | |
| return Colors::getColoredString($string,$foreground_color,$background_color); | |
| } | |
| function usage($filename) { | |
| global $newline; | |
| $usage = array( | |
| 'mastostats: get Mastodon network statistics from instances.mastodon.xyz, updates every 30 seconds', | |
| '', | |
| 'Usage: '.$filename.' [more] [<topinstances>] [nocolour]', | |
| '', | |
| 'more: Shows more statistics - ranks the top instances by statuses and connections as well as users', | |
| '<topinstances>: Replace with a number to show the top <topinstances> number of instances. Defaults to 10.', | |
| 'nocolour: (or \'nocolor\'): Output will not be coloured.', | |
| '' | |
| ); | |
| echo implode($newline,$usage); | |
| } | |
| function comparison_by($property,$a,$b) { | |
| if ((!property_exists($a,$property)) || (!property_exists($b,$property))) throw new Exception("Property does not exist in a passed object"); | |
| if ($a->$property == 'unknown') $a->$property = 0; | |
| if ($b->$property == 'unknown') $b->$property = 0; | |
| if ($a->$property == $b->$property) return 0; | |
| return ($a->$property > $b->$property ? -1 : 1); | |
| } | |
| function printinstancestats($instance_array,$title) { | |
| global $newline,$morestats,$topinstances; | |
| global $users,$statuses,$connections; | |
| uasort($instance_array,function($a,$b) { | |
| return comparison_by('users',$a,$b); | |
| }); | |
| echo getColoredString($newline.'Top ','white').getColoredString($topinstances.' ','light_green').$title.getColoredString(':','white').$newline; | |
| if ($morestats) echo getColoredString('[By users]','light_cyan').$newline; | |
| foreach (array_slice($instance_array,0,$topinstances) as $instance=>$instance_obj) { | |
| echo getColoredString($instance,($instance_obj->up?'light_purple':'red')).getColoredString(': ','white'). | |
| getColoredString($instance_obj->users.' users ','light_cyan'). | |
| getColoredString('(','white').getColoredString((int)((int)($instance_obj->users)/$users*100).'%','light_green').getColoredString(') - ','white'). | |
| getColoredString($instance_obj->statuses.' statuses ','light_red'). | |
| getColoredString('(','white').getColoredString((int)((int)($instance_obj->statuses)/$statuses*100).'%','light_green').getColoredString(') - ','white'). | |
| getColoredString($instance_obj->connections.' connections','cyan').$newline; | |
| } | |
| if ($morestats) { | |
| uasort($instance_array,function($a,$b) { | |
| return comparison_by('statuses',$a,$b); | |
| }); | |
| echo getColoredString('[By statuses]','light_red').$newline; | |
| foreach (array_slice($instance_array,0,$topinstances) as $instance=>$instance_obj) { | |
| echo getColoredString($instance,($instance_obj->up?'light_purple':'red')).getColoredString(': ','white'). | |
| getColoredString($instance_obj->statuses.' statuses ','light_red'). | |
| getColoredString('(','white').getColoredString((int)((int)($instance_obj->statuses)/$statuses*100).'%','light_green').getColoredString(') - ','white'). | |
| getColoredString($instance_obj->users.' users ','light_cyan'). | |
| getColoredString('(','white').getColoredString((int)((int)($instance_obj->users)/$users*100).'%','light_green').getColoredString(') - ','white'). | |
| getColoredString($instance_obj->connections.' connections','cyan').$newline; | |
| } | |
| uasort($instance_array,function($a,$b) { | |
| return comparison_by('connections',$a,$b); | |
| }); | |
| echo getColoredString('[By connections]','cyan').$newline; | |
| foreach (array_slice($instance_array,0,$topinstances) as $instance=>$instance_obj) { | |
| echo getColoredString($instance,($instance_obj->up?'light_purple':'red')).getColoredString(': ','white'). | |
| getColoredString($instance_obj->connections.' connections','cyan').getColoredString(' - ','white'). | |
| getColoredString($instance_obj->users.' users ','light_cyan'). | |
| getColoredString('(','white').getColoredString((int)((int)($instance_obj->users)/$users*100).'%','light_green').getColoredString(') - ','white'). | |
| getColoredString($instance_obj->statuses.' statuses ','light_red'). | |
| getColoredString('(','white').getColoredString((int)((int)($instance_obj->statuses)/$statuses*100).'%','light_green').getColoredString(')','white').$newline; | |
| } | |
| } | |
| } | |
| $hit_once = false; | |
| $old_users = 0; | |
| $new_users = 0; | |
| $new_users_since_start = 0; | |
| $old_statuses = 0; | |
| $new_statuses = 0; | |
| $new_statuses_since_start = 0; | |
| $newline = "\r\n"; | |
| $unused_array = array(); | |
| // It's a shame I have to do this, but... the following array will contain manually-added instances that are known to (now, or in the past) misrepresent their user count. | |
| // Instances in this list will be hardcoded to show "unknown" (ie, 0) users. | |
| $misbehaving_instances = array('mastodon.potproject.net'); | |
| // arguments | |
| $topinstances = 10; | |
| $morestats = false; | |
| $colour = true; | |
| if ($argc > 1) { | |
| $filename = array_shift($argv); | |
| foreach ($argv as $arg) { | |
| $arglower = str_replace('-','',strtolower($arg)); | |
| if ($arglower == "more") { | |
| $morestats = true; | |
| continue; | |
| } | |
| if (($arglower == "nocolour") || ($arglower == "nocolor")) { // people will use the spelling that suits them, better to support both | |
| $colour = false; | |
| } | |
| if (is_numeric($arg)) { | |
| $topinstances = $arg; | |
| } | |
| if ($arglower == "help") die(usage($filename)); | |
| } | |
| } | |
| while(1) { | |
| $array = @json_decode(file_get_contents('https://instances.mastodon.xyz/instances.json')); | |
| if (!$array) { | |
| if (!$hit_once) { | |
| echo getColoredString("Could not contact instances.mastodon.xyz, trying again in 30 seconds...",'red').$newline; | |
| } | |
| sleep(60); | |
| continue; | |
| } | |
| // clear screen | |
| if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { | |
| proc_close(proc_open('cmd /c cls',array(STDIN,STDOUT,STDERR),$unused_array)); | |
| } else { | |
| echo chr(27).chr(91).'H'.chr(27).chr(91).'J'; | |
| } | |
| $count = count($array); | |
| $open_instances = $all_instances = array(); | |
| $users = 0; | |
| $open_instance_count = 0; | |
| $open_up_instance_count = 0; | |
| $up_instance_count = 0; | |
| $statuses = 0; | |
| $connections = 0; | |
| // iterate through all instances to get usercount, open instance list etc. | |
| foreach($array as $instance) { | |
| if ((in_array($instance->name,$misbehaving_instances)) || (!property_exists($instance,'users'))) $instance->users = 'unknown'; | |
| if (!property_exists($instance,'statuses')) $instance->statuses = 'unknown'; | |
| if (!property_exists($instance,'connections')) $instance->connections = 'unknown'; | |
| $users += $instance->users; | |
| $statuses += $instance->statuses; | |
| $connections += $instance->connections; | |
| if (@$instance->openRegistrations == true) { | |
| $open_instance_count++; | |
| $open_instances[(!$instance->up ? '[DOWN] ' : '').$instance->name] = (object)array('users'=>$instance->users,'statuses'=>$instance->statuses,'connections'=>$instance->connections,'up'=>$instance->up); | |
| if (@$instance->up == true) $open_up_instance_count++; | |
| } | |
| $all_instances[(!$instance->up ? '[DOWN] ' : '').$instance->name] = (object)array('users'=>$instance->users,'statuses'=>$instance->statuses,'connections'=>$instance->connections,'up'=>$instance->up); | |
| if (@$instance->up == true) $up_instance_count++; | |
| } | |
| echo getColoredString('For news and updates follow : ','white') . | |
| getColoredString('@','light_green') . getColoredString('slipstream','yellow') . getColoredString('@','light_green') . getColoredString('mastodon.social','yellow') . $newline; | |
| echo getColoredString('Instance count..............: ','white') . getColoredString($count,'yellow') . | |
| getColoredString(' (','white') . getColoredString($up_instance_count,'light_green') . getColoredString(' up)','white') . $newline; | |
| echo getColoredString('Open instances..............: ','white') . getColoredString($open_instance_count,'yellow') . | |
| getColoredString(' (','white') . getColoredString($open_up_instance_count,'light_green') . getColoredString(' up)','white') . $newline; | |
| echo getColoredString('Total users.................: ','white') . getColoredString($users,'yellow'); | |
| if (($old_users != 0) && ($old_users != $users)) { | |
| $new_users = $users - $old_users; | |
| if ($new_users < 0) $new_users = 0; | |
| $new_users_since_start += $new_users; | |
| echo getColoredString(' (','white').getColoredString('+' . $new_users,'light_green') . getColoredString(')','white'); | |
| } else if ($new_users > 0) { | |
| echo getColoredString(' (','white').getColoredString('+' . $new_users,'light_green') . getColoredString(')','white'); | |
| } | |
| echo $newline; | |
| echo getColoredString('New users...................: ','white') . | |
| getColoredString($new_users_since_start,'green') . getColoredString(' since start of script','white') . $newline; | |
| echo getColoredString('Average users/instance......: ','white') . getColoredString('~' . (int)($users/$count),'yellow') . $newline; | |
| echo getColoredString('Total statuses..............: ','white') . getColoredString($statuses,'yellow'); | |
| if (($old_statuses != 0) && ($old_statuses != $statuses)) { | |
| $new_statuses = $statuses - $old_statuses; | |
| if ($new_statuses < 0) $new_statuses = 0; | |
| $new_statuses_since_start += $new_statuses; | |
| echo getColoredString(' (','white') . getColoredString('+' . $new_statuses,'light_green') . getColoredString(')','white'); | |
| } else if ($new_statuses > 0) { | |
| echo getColoredString(' (','white') . getColoredString('+' . $new_statuses,'light_green') . getColoredString(')','white'); | |
| } | |
| echo $newline; | |
| echo getColoredString('New statuses................: ','white') . getColoredString($new_statuses_since_start,'green') . getColoredString(' since start of script','white') . $newline; | |
| echo getColoredString('Average statuses/instance...: ','white') . getColoredString('~' . (int)($statuses/$count),'yellow') . $newline; | |
| echo getColoredString('Average connections/instance: ','white') . getColoredString('~' . (int)($connections/$count),'yellow') . $newline; | |
| $old_users = $users; | |
| $old_statuses = $statuses; | |
| printinstancestats($open_instances,getColoredString('open instances','white')); | |
| printinstancestats($all_instances,getColoredString('instances overall','white')); | |
| $hit_once = true; | |
| // wait 60 seconds for the next round | |
| sleep(60); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment