123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- #!/bin/php
- <?php
- /*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- define('N',"\n");
- $inifp='crawler.ini';
- $help='DESCRIZIONE
- Questo script prende una lista di istanze mastodon sorellate, ciascuna
- con (o anche senza, però sarebbe meglio con) una relativa lista di
- istanze da essa bloccate, e genera una lista delle istanze note alle
- istanze sorellate, escludendone quelle bloccate - più, al momento,
- quelle il cui endpoint [istanza]/api/v1/instance non risponde, e quelle
- che hanno chiusa la registrazione di nuovi utenti.
- SINTASSI
- crawler.php [opzioni]
- OPZIONI
- -i, --inifp
- Imposta il file di configurazione (per default "'.$inifp.'").
- Tutte le altre opzioni, che siano specificate prima o dopo questa,
- hanno la precedenza su quelle definite nel file di configurazione.
- -t, --timeout
- Imposta il timeout delle richieste http.
- -e, --excludeafter
- Imposta il lasso di tempo (in secondi) dopo il quale un\'istanza che
- non si identifica (il cui endpoint [istanza]/api/v1/instance non
- risponde) viene eliminata dal listone di tutte le istanze testate.
- -b, --biglistfp
- Imposta il file da cui leggere le istanze già testate in passato (se
- non è specificata l\'opzione "-d", vedi sotto) e in cui scrivere
- il listone di tutte le istanze testate.
- -p, --prodlistfp
- Imposta il file in cui scrivere la lista delle istanze occhei.
- -s, --sistersfp
- Imposta il file da cui leggere le istanze sorelle e le relative liste
- di istanze sospese-silenziate.
- -d, --dontloadbl
- Evita di caricare il listone delle istanze già testate in passato.
- -h, --help
- Mostra questo aiuto ed esce.
- This program comes with ABSOLUTELY NO WARRANTY; for details see
- the source.
- This is free software, and you are welcome to redistribute it under
- certain conditions; see <http://www.gnu.org/licenses/> for details.'.N;
- function mexit($msg,$code) {
- echo($msg);
- exit($code);
- }
- $opts=array(
- 'excludeafter'=>60*60*24*30,
- 'sistersfp'=>'istanzesorelle',
- 'dontloadbl'=>0,
- 'timeout'=>5,
- 'biglistfp'=>'listona.json',
- 'prodlistfp'=>'listina.json'
- );
- for ($i=1; $i<$argc; $i++) {
- if ($argv[$i]=='-i' || $argv[$i]=='--inifp') {
- if ($i+1>=$argc || $argv[$i+1]=='')
- mexit('L’opzione «'.$argv[$i].'» richiede di specificare un file di configurazione (usa «-h» per vedere la guida).'.N,1);
- $i++;
- $inifp=$argv[$i];
- if (!file_exists($inifp) || !is_file($inifp) || !is_readable($inifp))
- mexit('"'.$inifp.'" non esiste, non è un file o non è leggibile.'.N,1);
- }
- }
- if (file_exists($inifp)) {
- $buf=@parse_ini_file($inifp);
- if ($buf!==false) {
- foreach ($buf as $key=>$val) {
- if (array_key_exists($key,$opts))
- $opts[$key]=$val;
- }
- } else {
- echo('Attenzione: non ho potuto leggere la configurazione dal file "'.$inifp.'", potrebbe essere non leggibile o corrotto.'.N);
- }
- }
- $f=@fopen($inifp,'w');
- if ($f!==false) {
- foreach ($opts as $key=>$val)
- fwrite($f,$key.'='.$val.N);
- fclose($f);
- } else {
- echo('Attenzione: non ho potuto salvare la configurazione nel file "'.$inifp.'".'.N);
- }
- for ($i=1; $i<$argc; $i++) {
- if (substr($argv[$i],0,1)=='-') {
- switch($argv[$i]) {
- case '-i':
- case '--inifp':
- $i++;
- break;
- case '-e':
- case '--excludeafter':
- if ($i+1>=$argc || preg_match('/^[0-9]+$/',$argv[$i+1])!==1)
- mexit('L’opzione «'.$argv[$i].'» richiede un parametro numerico intero (usa «-h» per vedere la guida).'.N,1);
- $i++;
- $opts['excludeafter']=$argv[$i];
- break;
- case '-t':
- case '--timeout':
- if ($i+1>=$argc || preg_match('/^[0-9]+$/',$argv[$i+1])!==1)
- mexit('L’opzione «'.$argv[$i].'» richiede un parametro numerico intero (usa «-h» per vedere la guida).'.N,1);
- $i++;
- $opts['timeout']=$argv[$i];
- break;
- case '-b':
- case '--biglistfp':
- if ($i+1>=$argc || $argv[$i+1]=='')
- mexit('L’opzione «'.$argv[$i].'» richiede un parametro di tipo file (usa «-h» per vedere la guida).'.N,1);
- $i++;
- $opts['biglistfp']=$argv[$i];
- break;
- case '-p':
- case '--biglistfp':
- if ($i+1>=$argc || $argv[$i+1]=='')
- mexit('L’opzione «'.$argv[$i].'» richiede un parametro di tipo file (usa «-h» per vedere la guida).'.N,1);
- $i++;
- $opts['biglistfp']=$argv[$i];
- break;
- case '-s':
- case '--sistersfp':
- if ($i+1>=$argc || $argv[$i+1]=='')
- mexit('L’opzione «'.$argv[$i].'» richiede un parametro di tipo file (usa «-h» per vedere la guida).'.N,1);
- $i++;
- $opts['sistersfp']=$argv[$i];
- break;
- case '-d':
- case '--dontloadbl':
- $opts['dontloadbl']=1;
- break;
- case '-h':
- case '--help':
- mexit($help,1);
- break;
- default:
- mexit('Opzione "'.$argv[$i].'" sconosciuta (usa «-h» per vedere la guida).'.N,1);
- break;
- }
- } else {
- mexit('Opzione "'.$argv[$i].'" sconosciuta (usa «-h» per vedere la guida).'.N,1);
- }
- }
- $sisters=array();
- echo('Carico il file delle istanze sorelle ("'.$opts['sistersfp'].'") ... ');
- $buf=@file_get_contents($opts['sistersfp']);
- if ($buf!==false) {
- echo('OK :-)'.N);
- $buf=explode(N,$buf);
- foreach ($buf as $val) {
- if ($val!='' && $val{0}!='#') {
- $kv=explode('|',$val);
- if ($kv[1]=='') $kv[1]=NULL;
- $sisters[$kv[0]]=$kv[1];
- }
- }
- } else {
- mexit(N.'Non ho potuto aprire il file delle istanze sorelle "'.$opts['sistersfp'].'", muoio.'.N,1);
- }
- if (count($sisters)<1)
- mexit('Il file delle istanze sorelle "'.$opts['sistersfp'].'" non contiene alcuna voce, muoio.'.N,1);
- $biglist=array();
- if ($opts['dontloadbl']==0) {
- if (file_exists($opts['biglistfp']) && is_file($opts['biglistfp']) && is_readable($opts['biglistfp'])) {
- echo('Carico la listona pre-esistente ("'.$opts['biglistfp'].'") ... ');
- $buf=@file_get_contents($opts['biglistfp']);
- if ($buf!==false) {
- echo('OK :-)'.N);
- $biglist=json_decode($buf,true);
- } else {
- echo('ERRORE :-('.N);
- }
- }
- }
- $context=stream_context_create(array('http'=>array('timeout'=>$opts['timeout'])));
- $blinstances=array();
- foreach ($sisters as $dom=>$bluri) {
- if (!is_null($bluri)) {
- echo('Recupero la lista delle istanze bloccate da "'.$dom.'" ("'.$bluri.'") ... ');
- $f=@fopen($bluri,'r',false,$context);
- if ($f!==false) {
- // le prime 4 righe non ci interessano
- for ($i=0; $i<4; $i++)
- fgets($f);
- while (!feof($f)) {
- $lin=fgets($f);
- if (preg_match('/^\|([^\|]*)\|([^\|]*)\|([^\|]*)\|$/',$lin,$buf)===1)
- $blinstances[]=$buf[1];
- }
- fclose($f);
- echo('OK :-)'.N);
- } else {
- echo('ERRORE :-('.N);
- }
- } else {
- echo('NON recupero la lista delle istanze bloccate da "'.$dom.'": la url della stessa non è definita.'.N);
- }
- }
- ksort($blinstances);
- foreach ($sisters as $dom=>$bluri) {
- echo('Recupero la lista delle istanze note a "'.$dom.'" ... ');
- $buf=@file_get_contents('https://'.$dom.'/api/v1/instance/peers',false,$context);
- if ($buf!==false) {
- echo('OK :-)'.N);
- $peers=json_decode($buf,true);
- foreach ($peers as $pdom) {
- if (!in_array($pdom,$blinstances) && !array_key_exists($pdom,$biglist)) {
- $biglist[$pdom]=NULL;
- }
- }
- } else {
- echo('ERRORE :-('.N);
- }
- }
- ksort($biglist);
- $prodlist=array();
- $i=0;
- $qinst=count($biglist);
- foreach ($biglist as $dom=>$oinfo) {
- echo('Recupero le informazioni su "'.$dom.'" ('.($i+1).'/'.$qinst.' - '.round(100/$qinst*$i).'%) ... ');
- $buf=@file_get_contents('https://'.$dom.'/api/v1/instance',false,$context);
- if ($buf!==false) {
- echo('OK :-)'.N);
- $info=json_decode($buf,true);
- $info['cr-last_checked']=time();
- $info['cr-was_ok']=true;
- $biglist[$dom]=$info;
- if (!array_key_exists('registrations',$info) || $info['registrations']==true) {
- $prodlist[$dom]=$info;
- echo('"'.$dom.'" aggiunta alla lista delle istanze ok! :-)'.N);
- }
- } else {
- echo('ERRORE :-( ... ');
- if (is_null($oinfo) || time()-$oinfo['cr-last_checked']<=$opts['excludeafter']) {
- echo('ma riproveremo...'.N);
- $oinfo['cr-last_checked']=time();
- $oinfo['cr-was_ok']=false;
- $biglist[$dom]=$oinfo;
- } else {
- echo('e non riproveremo...'.N);
- }
- }
- $i++;
- }
- $json=json_encode($biglist,JSON_PRETTY_PRINT);
- file_put_contents($opts['biglistfp'],$json);
- $json=json_encode($prodlist,JSON_PRETTY_PRINT);
- file_put_contents($opts['prodlistfp'],$json);
- echo('Totale istanze nella listona: '.count($biglist).N);
- echo('Totale istanze nella listina di quelle occhei: '.count($prodlist).N);
- ?>
|