this.');
exit(0);
}
$bt=hrtime(true);
$btu=time();
$dlanguc=strtoupper($dlang);
require '../lib/n2es.php';
require '../lib/gracetime.php';
require '../lib/fnum.php';
use function mysqli_real_escape_string as myesc;
/*$dlang='fr';
$dtzbl=['ca'=>'Europe/Madrid','en'=>'Europe/London','es'=>'Europe/Madrid','fr'=>'Europe/Paris','it'=>'Europe/Rome'];
date_default_timezone_set($dtzbl[$dlang]);*/
$lc=localeconv();
$debug='';
debug(date('r',$btu).N,$debug);
debug('REQUEST_URI: '.$_SERVER['REQUEST_URI'].N,$debug);
debug('$_GET: '.print_r($_GET,true),$debug);
debug('LOCALE: '.setlocale(LC_ALL,0).N,$debug);
// an instance is displayed as "New" if its age, relative to the InsertTS field, is less or equal than this (currently 30 days)
$oldline=30*24*60*60;
// an instance is considered dead if the last time it responded is before the graceline (see code below); we fix it at start of today - $gracetime
// $gracetime is defined in mustard/include/gracetime.php
$graceline=gmmktime(0,0,0,gmdate('n',$btu),gmdate('j',$btu),gmdate('Y',$btu))-$gracetime;
if (array_key_exists('id',$_GET) && preg_match('/^\d+$/',$_GET['id'])===1) {
$_GET['id']+=0;
$single=true;
} else {
$single=false;
}
//$getc=count($_GET);
//forcing $getc to 1 to never display the explanation of search engine workings
$getc=1;
$minudef=10;
$minumax=4294967295;
$maxudef=30000;
$maxumax=4294967295;
$minaudef=10;
$minaumax=4294967295;
$mincdef='';
$mincmax=16777215;
$link=mysqli_connect($conf['db_host'],$conf['db_user_name'],$conf['db_user_password'],$conf['db_name'],$conf['db_port'],$conf['db_socket']) or muorimeglio(_('Couldn’t connect to database: ').mysqli_connect_error().' ['.mysqli_connect_errno().']',false);
mysqli_set_charset($link,'utf8mb4');
// if and when ... put it soon after below
/*
*/
echo('
'.N);
if ($single) {
setfedipact();
echo('↑ '._('Go to search').'
'.N);
$p=1;
$que='SELECT * FROM Instances WHERE ID='.$_GET['id'];
} else {
echo('
'._('Instances').'
'.N);
setfedipact();
$que='SELECT COUNT(ID) AS Unknown, SUM(UserCount) AS UnknownU FROM Instances WHERE IsMastodon=1 AND Visible=1 AND LastOkCheckTS>='.$graceline.' AND Threads IS NULL';
if ($cfedipact>0)
$que.=' AND URI NOT IN ('.$fedipact['uris_me'].')';
$res=tquery($que,__LINE__);
$row=mysqli_fetch_assoc($res);
$metastats['unknown']=['instances'=>$row['Unknown'], 'users'=>nulltozero($row['UnknownU'])];
$que='SELECT COUNT(ID) AS Suspending, SUM(UserCount) AS SuspendingU FROM Instances WHERE IsMastodon=1 AND Visible=1 AND LastOkCheckTS>='.$graceline;
if ($cfedipact>0)
$que.=' AND (Threads="suspended" OR URI IN ('.$fedipact['uris_me'].'))';
else
$que.=' AND Threads="suspended"';
$res=tquery($que,__LINE__);
$row=mysqli_fetch_assoc($res);
$metastats['suspending']=['instances'=>$row['Suspending'], 'users'=>nulltozero($row['SuspendingU'])];
$res=tquery('SELECT COUNT(ID) AS Silencing, SUM(UserCount) AS SilencingU FROM Instances WHERE IsMastodon=1 AND Visible=1 AND LastOkCheckTS>='.$graceline.' AND Threads="limited"',__LINE__);
$row=mysqli_fetch_assoc($res);
$metastats['limiting']=['instances'=>$row['Silencing'], 'users'=>nulltozero($row['SilencingU'])];
$metastats['fpsuspending']['instances']=0;
$metastats['fpsuspending']['users']=0;
$metastats['fpliars']['instances']=0;
$metastats['fpliars']['users']=0;
$metastats['fpliars']['instlist']=[];
if ($cfedipact>0) {
$res=tquery('SELECT COUNT(ID) AS FPSuspending, SUM(UserCount) AS FPSuspendingU FROM Instances WHERE IsMastodon=1 AND Visible=1 AND LastOkCheckTS>='.$graceline.' AND URI IN ('.$fedipact['uris_me'].')',__LINE__);
$row=mysqli_fetch_assoc($res);
$metastats['fpsuspending']['instances']=$row['FPSuspending'];
$metastats['fpsuspending']['users']=nulltozero($row['FPSuspendingU']);
$res=tquery('SELECT URI, UserCount FROM Instances WHERE IsMastodon=1 AND Visible=1 AND LastOkCheckTS>='.$graceline.' AND Threads="accessible" AND URI IN ('.$fedipact['uris_me'].')',__LINE__);
while ($row=mysqli_fetch_assoc($res)) {
$metastats['fpliars']['instances']++;
$metastats['fpliars']['users']+=nulltozero($row['UserCount']);
$metastats['fpliars']['instlist'][]=['uri'=>$row['URI'], 'usercount'=>nulltozero($row['UserCount'])];
}
}
$res=tquery('SELECT COUNT(ID) AS tinsts, SUM(UserCount) AS tusers, SUM(StatusCount) AS tstatuses, SUM(ActiveUsersMonth) AS tactusers FROM Instances WHERE IsMastodon=1 AND Visible=1 AND LastOkCheckTS>='.$graceline,__LINE__);
$row=mysqli_fetch_assoc($res);
echo(_('This search engine for Mastodon instances is based on a database that gets updated by our crawler every night (CET). Instances are considered new for 30 days after they are discovered. When an instance has not responded to our daily checks for more than 30 days it’s no longer considered in statistics and searches and it gets checked only on the first of the month, rather than daily, until it possibly responds again. “Random ordering” of results varies daily.
Default search criteria reflect our fondness for a decentralized and egalitarian Fediverse and our attempt to exclude instances accepting fascist, racist, sexist, ableist or sovereignist contents by marking them as noxious.
').N);
printf(_('We currently count %s Mastodon instances, with %s users (%s active during last month) and %s published statuses. [Show Threads moderation statistics]
'), fnum($row['tinsts'],$lc), fnum($row['tusers'],$lc), fnum($row['tactusers'],$lc), fnum($row['tstatuses'],$lc));
//echo ''.print_r($metastats,true).'
'.N;
$metastats['known']=[
'instances'=>$row['tinsts']-$metastats['unknown']['instances'],
'users'=>$row['tusers']-$metastats['unknown']['users']
];
$metastats['known']['iperc']=$metastats['known']['instances']*100/$row['tinsts'];
$metastats['known']['uperc']=$metastats['known']['users']*100/$row['tusers'];
$metastats['unknown']['iperc']=$metastats['unknown']['instances']*100/$row['tinsts'];
$metastats['unknown']['uperc']=$metastats['unknown']['users']*100/$row['tusers'];
$metastats['suspending']['iperc']=$metastats['suspending']['instances']*100/$row['tinsts'];
$metastats['suspending']['uperc']=$metastats['suspending']['users']*100/$row['tusers'];
$metastats['suspending']['kiperc']=$metastats['suspending']['instances']*100/$metastats['known']['instances'];
$metastats['suspending']['kuperc']=$metastats['suspending']['users']*100/$metastats['known']['users'];
$metastats['fpsuspending']['iperc']=$metastats['fpsuspending']['instances']*100/$row['tinsts'];
$metastats['fpsuspending']['uperc']=$metastats['fpsuspending']['users']*100/$row['tusers'];
$metastats['fpsuspending']['kiperc']=$metastats['fpsuspending']['instances']*100/$metastats['known']['instances'];
$metastats['fpsuspending']['kuperc']=$metastats['fpsuspending']['users']*100/$metastats['known']['users'];
$metastats['limiting']['iperc']=$metastats['limiting']['instances']*100/$row['tinsts'];
$metastats['limiting']['uperc']=$metastats['limiting']['users']*100/$row['tusers'];
$metastats['limiting']['kiperc']=$metastats['limiting']['instances']*100/$metastats['known']['instances'];
$metastats['limiting']['kuperc']=$metastats['limiting']['users']*100/$metastats['known']['users'];
$metastats['notsusporlim']=[
'instances'=>$row['tinsts']-$metastats['unknown']['instances']-$metastats['suspending']['instances']-$metastats['limiting']['instances'],
'users'=>$row['tusers']-$metastats['unknown']['users']-$metastats['suspending']['users']-$metastats['limiting']['users']
];
$metastats['notsusporlim']['iperc']=$metastats['notsusporlim']['instances']*100/$row['tinsts'];
$metastats['notsusporlim']['uperc']=$metastats['notsusporlim']['users']*100/$row['tusers'];
$metastats['notsusporlim']['kiperc']=$metastats['notsusporlim']['instances']*100/$metastats['known']['instances'];
$metastats['notsusporlim']['kuperc']=$metastats['notsusporlim']['users']*100/$metastats['known']['users'];
$metastats['susporlim']=[
'instances'=>$metastats['suspending']['instances']+$metastats['limiting']['instances'],
'users'=>$metastats['suspending']['users']+$metastats['limiting']['users']
];
$metastats['susporlim']['iperc']=$metastats['susporlim']['instances']*100/$row['tinsts'];
$metastats['susporlim']['uperc']=$metastats['susporlim']['users']*100/$row['tusers'];
$metastats['susporlim']['kiperc']=$metastats['susporlim']['instances']*100/$metastats['known']['instances'];
$metastats['susporlim']['kuperc']=$metastats['susporlim']['users']*100/$metastats['known']['users'];
debug('fpsuspending: instances: '.$metastats['fpsuspending']['instances'].'; users: '.$metastats['fpsuspending']['users'].N.'fpliars: instances: '.$metastats['fpliars']['instances'].'; users: '.$metastats['fpliars']['users'].N,$debug);
if (count($metastats['fpliars']['instlist'])>0)
foreach ($metastats['fpliars']['instlist'] as $val)
debug($val['uri'].': '.$val['usercount'].N,$debug);
echo
''.N;
if ((array_key_exists('exnox',$_GET) && $_GET['exnox']=='1') || !array_key_exists('exnox',$_GET)) {
$_GET['cbexnox']=' checked';
$_GET['exnox']=1;
} else {
$_GET['cbexnox']='';
$_GET['exnox']=0;
}
if ((array_key_exists('exregc',$_GET) && $_GET['exregc']=='1') || !array_key_exists('exregc',$_GET)) {
$_GET['cbexregc']=' checked';
$_GET['exregc']=1;
} else {
$_GET['cbexregc']='';
$_GET['exregc']=0;
}
// if ((array_key_exists('inths',$_GET) && $_GET['inths']=='1') || !array_key_exists('inths',$_GET)) {
if (array_key_exists('inths',$_GET) && $_GET['inths']=='1') {
$_GET['cbinths']=' checked';
$_GET['inths']=1;
} else {
$_GET['cbinths']='';
$_GET['inths']=0;
}
if (array_key_exists('exappr',$_GET) && $_GET['exappr']=='1') {
$_GET['cbexappr']=' checked';
$_GET['exappr']=1;
} else {
$_GET['cbexappr']='';
$_GET['exappr']=0;
}
if (array_key_exists('exlcko',$_GET) && $_GET['exlcko']=='1') {
$_GET['cbexlcko']=' checked';
$_GET['exlcko']=1;
} else {
$_GET['cbexlcko']='';
$_GET['exlcko']=0;
}
if (array_key_exists('lang',$_GET)) {
if (preg_match('#^[0-9]+$#',$_GET['lang'])===1)
$_GET['lang']=$_GET['lang']+0;
else
$_GET['lang']=0;
} else {
$res=tquery('SELECT ID FROM Languages WHERE Code="'.myesc($link,$dlang).'"',__LINE__);
if (mysqli_num_rows($res)>0) {
$row=mysqli_fetch_assoc($res);
$_GET['lang']=$row['ID'];
} else {
$_GET['lang']=0;
}
}
if ($_GET['lang']>5000000000) $_GET['lang']=0;
if (array_key_exists('desc',$_GET) && preg_match('#^.+$#',$_GET['lang'])===1)
$_GET['desc']=trim(n2es($_GET['desc']));
else
$_GET['desc']='';
if (mb_strlen($_GET['desc'])>64) $_GET['desc']='';
ckgnum('minu',$minudef,$minumax);
ckgnum('maxu',$maxudef,$maxumax);
if (is_int($_GET['maxu']) && is_int($_GET['minu']) && $_GET['maxu']<$_GET['minu']) $_GET['maxu']=$_GET['minu'];
ckgnum('minau',$minaudef,$minaumax);
ckgnum('minc',$mincdef,$mincmax);
$order=[
'rand'=>['t'=>_('Random'), 'q'=>'Instances.RPos ASC'],
'invold'=>['t'=>_('By users’ involvement (active users / users), descending'), 'q'=>'(Instances.ActiveUsersMonth / Instances.UserCount) DESC'],
'invola'=>['t'=>_('By users’ involvement (active users / users), ascending'), 'q'=>'(Instances.ActiveUsersMonth / Instances.UserCount) ASC'],
'fseend'=>['t'=>_('By date and time of first sighting, descending'), 'q'=>'Instances.FirstSeen DESC'],
'fseena'=>['t'=>_('By date and time of first sighting, ascending'), 'q'=>'Instances.FirstSeen ASC'],
'tusersd'=>['t'=>_('By number of users, descending'), 'q'=>'Instances.UserCount DESC'],
'tusersa'=>['t'=>_('By number of users, ascending'), 'q'=>'Instances.UserCount ASC'],
'ausersd'=>['t'=>_('By number of active users, descending'), 'q'=>'Instances.ActiveUsersMonth DESC'],
'ausersa'=>['t'=>_('By number of active users, ascending'), 'q'=>'Instances.ActiveUsersMonth ASC'],
'checksd'=>['t'=>_('By responsiveness to our checks, descending'), 'q'=>'(Instances.OkChecks / Instances.TotChecks) DESC, Instances.TotChecks DESC'],
'checksa'=>['t'=>_('By responsiveness to our checks, ascending'), 'q'=>'(Instances.OkChecks / Instances.TotChecks) ASC, Instances.TotChecks ASC'],
'charsd'=>['t'=>_('By available characters per post, descending'), 'q'=>'Instances.MaxTootChars DESC'],
'charsa'=>['t'=>_('By available characters per post, ascending'), 'q'=>'Instances.MaxTootChars ASC'],
'noxd'=>['t'=>_('Noxious first (switches off “Exclude noxious”)'), 'q'=>'Instances.Noxious DESC']
];
if (!array_key_exists('ord',$_GET) || !array_key_exists($_GET['ord'],$order))
$_GET['ord']='rand';
// $res=tquery('SELECT COUNT(Instances.ID) AS Recomm FROM Instances LEFT JOIN InstOurLangs ON InstOurLangs.InstID=Instances.ID WHERE InstOurLangs.OurLangID='.$_GET['lang'].' AND Instances.IsMastodon=1 AND Instances.Visible=1 AND Instances.LastOkCheckTS>='.$graceline.' AND InstOurLangs.Pos=1 AND Instances.Priority>127',__LINE__);
$res=tquery('SELECT InstOurLangs.OurLangID FROM Instances LEFT JOIN InstOurLangs ON InstOurLangs.InstID=Instances.ID WHERE Instances.IsMastodon=1 AND Instances.Visible=1 AND Instances.LastOkCheckTS>='.$graceline.' AND InstOurLangs.Pos=1 AND Instances.Priority>127 GROUP BY InstOurLangs.OurLangID',__LINE__);
$langswri=[];// langs with recommended instances
while ($row=mysqli_fetch_assoc($res))
$langswri[]=$row['OurLangID'];
if (count($langswri)>0)
array_unshift($langswri,0);
if (in_array($_GET['lang'],$langswri))
$order['rand']=['t'=>_('Random, recommended first'), 'q'=>'Instances.Priority DESC, Instances.RPos ASC'];
$p=1;
if (array_key_exists('p',$_GET) && preg_match('#^[0-9]+$#',$_GET['p'])===1) $p=$_GET['p']+0;
echo(''._('Search instances').'
'.N);
($_GET['lang']==0) ? $selected=' selected' : $selected='';
echo '
'.N);
$joins=[];
$wheres=[];
$wheres[]='Instances.IsMastodon=1 AND Instances.Visible=1 AND Instances.LastOkCheckTS>='.$graceline;
if ($_GET['exnox']==1) $wheres[]='Instances.Noxious=0';
if ($_GET['exregc']==1) $wheres[]='Instances.RegOpen=1';
if ($_GET['exappr']==1) $wheres[]='Instances.RegReqApproval=0';
if ($_GET['exlcko']==1) $wheres[]='Instances.WasLastCheckOk=1';
/*if ($_GET['exlcko']==1) {
$joins[]='LEFT JOIN InstChecks AS InstChecks ON InstChecks.InstID=Instances.ID AND InstChecks.Time=(SELECT MAX(InstChecks.Time) AS MaxTime FROM InstChecks WHERE InstChecks.InstID=Instances.ID)';
$wheres[]='InstChecks.Status=1';
}*/
if ($_GET['inths']==1) {
if ($cfedipact>0)
$wheres[]='Instances.Threads="suspended" OR Instances.ID IN ('.implode(', ',$fedipact['instids']).')';
else
$wheres[]='Instances.Threads="suspended"';
}
if ($_GET['lang']>0) {
$joins[]='LEFT JOIN InstOurLangs ON InstOurLangs.InstID=Instances.ID';
$wheres[]='(InstOurLangs.OurLangID='.$_GET['lang'].' AND InstOurLangs.Pos=1)';
}
$buf=preg_replace('#%#','\%',myesc($link,$_GET['desc']));
if ($_GET['desc']!='') $wheres[]='(Instances.URI LIKE "%'.$buf.'%" OR Instances.Title LIKE "%'.$buf.'%" OR Instances.ShortDesc LIKE "%'.$buf.'%" OR Instances.LongDesc LIKE "%'.$buf.'%")';
if ($_GET['minu']!='') $wheres[]='Instances.UserCount>='.$_GET['minu'];
if ($_GET['maxu']!='') $wheres[]='Instances.UserCount<='.$_GET['maxu'];
if ($_GET['minau']!='') $wheres[]='Instances.ActiveUsersMonth>='.$_GET['minau'];
if ($_GET['minc']!='' && $_GET['minc']!='""') $wheres[]='Instances.MaxTootChars>='.$_GET['minc'];
$joins=implode(' ',$joins);
$wheres='WHERE '.implode(' AND ',$wheres);
$que='SELECT * FROM Instances '.$joins.' '.$wheres.' ORDER BY '.$order[$_GET['ord']]['q'];
}
debug('MAIN QUERY: «'.$que.'»'.N,$debug);
$res=tquery($que,__LINE__);
$itot=mysqli_num_rows($res);
debug('RESULTS: '.$itot.N,$debug);
/*if ($itot==0) {
echo(_('No instance matches with the search criteria.').N.''.N.'
'.N.'
'.N.'