diff --git a/mastblocksdump/mastblocksmerge.wip.sh b/mastblocksdump/mastblocksmerge.wip.sh
new file mode 100755
index 0000000..f1bbbac
--- /dev/null
+++ b/mastblocksdump/mastblocksmerge.wip.sh
@@ -0,0 +1,237 @@
+#!/bin/bash
+
+# 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 .
+
+MASTHOME='/var/lib/mastodon'
+MASTENVFP="$MASTHOME/live/.env.production"
+SISTERSFP="istanzesorelle"
+LOCAL=0
+INTERACTIVE=0
+
+HELP="SINTASSI
+ mastblocksmerge.sh [opzioni]
+DESCRIZIONE
+ Questo script integra i dati di una o più blocklist esterne nella
+ tabella domain_blocks di mastodon.
+ Legge i domini delle istanze di cui recuperare la blocklist da un file
+ di inizializzazione, per default \"$SISTERSP\" (formato del file:
+ un dominio per riga), prova a recuperare ciascuna blocklist da
+ https://[dominio]/domain_blocks.txt, costruisce dalle liste recuperate
+ un\'unica lista senza duplicati, si collega al db di mastodon e scrive
+ nella tabella domain_blocks i dati relativi alle istanze bloccate che
+ non sono già presenti nella tabella stessa.
+ Per la connessione al db di mastodon legge i dati necessari dal file
+ di configurazione di mastodon, per default
+ \"$MASTENVFP\"
+ È pensato per essere eseguito periodicamente da un cron job, come
+ utente mastodon oppure root oppure altro utente che abbia accesso in
+ lettura al file di configurazione di mastodon.
+OPZIONI
+ -H, --home
+ Definisce la home di mastodon (per default \"$MASTHOME\")
+ e di conseguenza il percorso del suo file di configurazione
+ (per default \"$MASTENVFP\").
+ È comunque possibile specificare individualmente il percorso
+ del file di configurazione di mastodon con l\'opzione che segue.
+ -e, --envfp
+ Definisce il percorso del file di configurazione di mastodon in uso.
+ -s, --sistersfp
+ Definisce il percorso del file di inizializzazione da cui leggere
+ la lista dei domini delle istanze sorelle.
+ -l, --local
+ Interpreta il file di inizializzazione come lista di file locali
+ contenenti blacklist (formato: un file per riga).
+ -i, --interactive
+ Modalità interattiva: se vengono nelle blocklist vengono trovate
+ istanze ancora non presenti nel database di mastodon, viene chiesto
+ per ciascuna se aggiungerla o meno.
+ -h, --help
+ Mostra questo aiuto ed esce."
+
+args=("$@")
+i=0
+while [ $i -lt ${#args[@]} ]; do
+ if [ "${args[$i]:0:1}" == "-" ]; then
+ case "${args[$i]}" in
+ "-H" | "--home" )
+ if [ -z "${args[$i+1]}" ]; then
+ echo "L'opzione \"${args[$i]}\" richiede un parametro (usa \"-h\" per l'aiuto)."
+ exit 1
+ else
+ ((i++))
+ MASTHOME=$(echo "${args[$i]}" | sed -e 's/\/$//')
+ MASTENVFP="$MASTHOME/live/.env.production"
+ fi
+ ;;
+ "-e" | "--envfp" )
+ if [ -z "${args[$i+1]}" ]; then
+ echo "L'opzione \"${args[$i]}\" richiede un parametro (usa \"-h\" per l'aiuto)."
+ exit 1
+ else
+ ((i++))
+ MASTENVFP="${args[$i]}"
+ fi
+ ;;
+ "-s" | "--sistersfp" )
+ if [ -z "${args[$i+1]}" ]; then
+ echo "L'opzione \"${args[$i]}\" richiede un parametro (usa \"-h\" per l'aiuto)."
+ exit 1
+ else
+ ((i++))
+ SISTERSFP="${args[$i]}"
+ fi
+ ;;
+ "-l" | "--local" )
+ LOCAL=1
+ ;;
+ "-i" | "--interactive" )
+ INTERACTIVE=1
+ ;;
+ "-h" | "--help" )
+ echo "$HELP"
+ exit 0
+ ;;
+ *)
+ echo "\"${args[$i]}\": opzione sconosciuta (usa \"-h\" per l'aiuto)."
+ exit 1
+ ;;
+ esac
+ else
+ echo "\"${args[$i]}\": opzione sconosciuta (usa \"-h\" per l'aiuto)."
+ exit 1
+ fi
+ ((i++))
+done
+
+[ ! -e "$MASTENVFP" ] && echo "\"$MASTENVFP\" non esiste, muoio (usa \"-h\" per l'aiuto)." && exit 1
+[ ! -f "$MASTENVFP" ] && echo "\"$MASTENVFP\" non è un file, muoio (usa \"-h\" per l'aiuto)." && exit 1
+[ ! -r "$MASTENVFP" ] && echo "\"$MASTENVFP\" non è leggibile, muoio (usa \"-h\" per l'aiuto)." && exit 1
+
+[ ! -e "$SISTERSFP" ] && echo "\"$SISTERSFP\" non esiste, muoio (usa \"-h\" per l'aiuto)." && exit 1
+[ ! -f "$SISTERSFP" ] && echo "\"$SISTERSFP\" non è un file, muoio (usa \"-h\" per l'aiuto)." && exit 1
+[ ! -r "$SISTERSFP" ] && echo "\"$SISTERSFP\" non è leggibile, muoio (usa \"-h\" per l'aiuto)." && exit 1
+
+DB_HOST=`grep 'DB_HOST' "$MASTENVFP"|sed -e 's/[^=]*=//'`
+DB_PORT=`grep 'DB_PORT' "$MASTENVFP"|sed -e 's/[^=]*=//'`
+DB_NAME=`grep 'DB_NAME' "$MASTENVFP"|sed -e 's/[^=]*=//'`
+DB_USER=`grep 'DB_USER' "$MASTENVFP"|sed -e 's/[^=]*=//'`
+DB_PASS=`grep 'DB_PASS' "$MASTENVFP"|sed -e 's/[^=]*=//'`
+
+IFS=$'\n'
+
+function decode {
+ #dominio
+ record[0]=$(echo "$1" | sed -e 's/\t.*//')
+ #data creazione
+ record[1]=$(echo "$1" | sed -e 's/^[^\t]*\t\([^\t]*\).*/\1/')
+ #data ultima modifica
+ record[2]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
+ #tipo di blocco
+ record[3]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
+ #rifiuto media
+ record[4]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
+ #rifiuto reports
+ record[5]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
+ #commento pubblico
+ record[6]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
+ if [ "${record[4]}" == "f" ]; then
+ record[4]="No"
+ elif [ "${record[4]}" == "t" ]; then
+ record[4]="Si"
+ fi
+ if [ "${record[5]}" == "f" ]; then
+ record[5]="No"
+ elif [ "${record[5]}" == "t" ]; then
+ record[5]="Si"
+ fi
+ if [ "${record[3]}" == "0" ]; then
+ record[3]="Silenziata"
+ elif [ "${record[3]}" == "1" ]; then
+ record[3]="Sospesa"
+ elif [ "${record[3]}" == "2" ]; then
+ record[3]="Nessuno"
+ fi
+}
+
+for sisdom in $(grep -P '^[^#]+[^\s]+' "$SISTERSFP"); do
+ if [ $LOCAL -eq 0 ]; then
+ blocks+="$(curl --connect-timeout 3 -s "https://$sisdom/domain_blocks.txt" | grep -P '^[^#]+[^\s]+')$IFS"
+ else
+ blocks+="$(cat "$sisdom" | grep -P '^[^#]+[^\s]+')$IFS"
+ fi
+done
+blocks=$(echo "$blocks" | head -n -1 | sort -u)
+echo "$blocks"
+echo "~~~~~~~~~~~~~~~~~~~~"
+okblocks=''
+for line in $blocks; do
+ dom=$(echo "$line" | sed -e 's/\t.*//' -e 's/\./\\./g')
+ echo "$okblocks" | grep -P "^$dom\t"
+ if [ $? -ne 0 ]; then
+ entries=$(echo "$blocks" | grep -P "^$dom\t")
+ howmany=$(echo "$entries" | wc -l)
+ if [ $howmany -gt 1 ]; then
+ if [ $INTERACTIVE -eq 1 ]; then
+ i=0
+ for entry in $entries; do
+ ((i++))
+ echo "$i: $entry"
+ done
+ read
+ else
+ # qui ci vorrebbe codice "intelligente" che sceglie la entry più recente, ma per ora così
+ okblocks+="$line$IFS"
+ fi
+ fi
+ fi
+done
+okblocks=$(echo "$okblocks" | head -n -1 | sort)
+echo "$okblocks"
+echo "~~~~~~~~~~~~~~~~~~~~"
+
+exit
+
+
+
+
+blocks=$(PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -p "$DB_PORT" -d "$DB_NAME" -U "$DB_USER" -c 'SELECT domain, updated_at, severity, public_comment FROM domain_blocks' -A -t -F $'\t')
+
+i=0
+for line in $allblocks; do
+ dom=$(echo "$line" | sed -e 's/\t.*//' -e 's/\./\\./g')
+ echo "$blocks" | grep -P "^$dom\t" &>/dev/null
+ [ $? -ne 0 ] && newblocks+="$line$IFS" && ((i++))
+done
+newblocks=$(echo "$newblocks" | head -n -1 | sort)
+
+[ $i -eq 0 ] && echo "Non ho trovato nessuna nuova istanza bloccata." && exit 0
+
+echo "Ho trovato $i istanza/e bloccata da aggiungere."
+
+if [ $INTERACTIVE -eq 1 ]; then
+ for line in $newblocks; do
+ decode "$line"
+ echo "Dominio: ${record[0]}; Data creaz.: ${record[1]}; Data ult. mod.: ${record[2]}; Tipo blocco: ${record[3]}; Rifiuto media: ${record[4]}; Rifiuto reports: ${record[5]}; Commento pub.: ${record[6]}"
+ ask=1
+ while [ $ask -eq 1 ]; do
+ read -p "Vuoi aggiungere questa istanza alla tabella delle istanze bloccate? [S/n] " inp
+ echo "$inp" | grep -P '^[sSnN]{0,1}$' &>/dev/null
+ [ $? -eq 0 ] && ask=0
+ done
+ if [ "$inp" == "" ] || [ "$inp" == "s" ] || [ "$inp" == "S" ]; then
+ buf+="$line$IFS"
+ fi
+ done
+ newblocks=$(echo "$buf" | head -n -1)
+fi
+
+echo "$newblocks" | PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -p "$DB_PORT" -d "$DB_NAME" -U "$DB_USER" -A -t -c "COPY domain_blocks ( domain, created_at, updated_at, severity, reject_media, reject_reports, public_comment ) FROM STDIN WITH ( FORMAT text, DELIMITER ' ' )"
diff --git a/mastblocksdump/php/domblocks.php b/mastblocksdump/php/domblocks.php
new file mode 100644
index 0000000..8fc6311
--- /dev/null
+++ b/mastblocksdump/php/domblocks.php
@@ -0,0 +1,38 @@
+null,
+ 'DB_PORT'=>null,
+ 'DB_NAME'=>null,
+ 'DB_USER'=>null,
+ 'DB_PASS'=>null
+);
+
+$confa=file($conffp,FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
+
+foreach ($confa as $line) {
+ if (preg_match('/^([A-Z_]+)=(.*)$/',$line,$buf)===1 && array_key_exists($buf[1],$conf))
+ $conf[$buf[1]]=$buf[2];
+}
+
+$dbconn=pg_connect('host='.$conf['DB_HOST'].' port='.$conf['DB_PORT'].' dbname='.$conf['DB_NAME'].' user='.$conf['DB_USER'].' password='.$conf['DB_PASS'])
+ or die('Connessione fallita: '.pg_last_error());
+
+$res=pg_query('SELECT domain, created_at, updated_at, severity, reject_media, reject_reports, public_comment FROM domain_blocks')
+ or die('Query fallita: '.pg_last_error());
+
+while ($row=pg_fetch_assoc($res))
+ $domblocks[]=$row;
+
+pg_free_result($res);
+pg_close($dbconn);
+
+echo(json_encode($domblocks));
+
+exit(0);
+
+?>
diff --git a/web/admin/crawler/.htaccess b/web/admin/crawler/.htaccess
new file mode 100644
index 0000000..93169e4
--- /dev/null
+++ b/web/admin/crawler/.htaccess
@@ -0,0 +1,2 @@
+Order deny,allow
+Deny from all
diff --git a/web/admin/crawler/blacklist_bida.txt b/web/admin/crawler/blacklist_bida.txt
deleted file mode 100644
index 7dfe535..0000000
--- a/web/admin/crawler/blacklist_bida.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-anitwitter.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-anitwitter.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-babymetal.party 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-baraag.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-bsd.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f https://mastodon.bida.im/@Ca_Gi/101270762003908554
-ediot.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-freespeechextremist.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-freespeech.firedragonstudios.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f https://mastodon.bida.im/@Ca_Gi/101344114624456297
-freezepeach.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-gorf.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-gs.smuglo.li 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-humblr.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 0 f f https://mastodon.bida.im/@cirku17/101399587014096355
-ika.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-mastodon.starrevolution.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f https://a.nom.pl/notice/450131
-mobile.co 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f https://mastodon.bida.im/@Ca_Gi/101355947506820592
-neckbeard.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f Instance suspended: neckbeard.xyz - anime nazi shit, irony bro admin
-newjack.city 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-noagendasocial.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 0 f f
-pawoo.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-pl.smuglo.li 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-porntoot.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 0 f f
-preteengirls.biz 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-quodverum.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f https://mastodon.bida.im/@Ca_Gi/101514801964087604
-sealion.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 0 f f
-shitposter.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 0 f f
-shitposter.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f https://mastodon.bida.im/@Ca_Gi/101270762003908554
-social.au2pb.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-social.heldscal.la 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-social.imirhil.fr 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-social.quodverum.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f Razzisti
-social.targaryen.house 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 0 f f
-switter.at 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 0 f f https://mastodon.bida.im/@jops/101404791975700441
-toot.love 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 0 f f
-unsafe.space 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-woofer.alfter.us 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
-wrongthink.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:05.111111 1 f f
diff --git a/web/admin/crawler/blacklist_cagi.txt b/web/admin/crawler/blacklist_cagi.txt
deleted file mode 100644
index b8f989e..0000000
--- a/web/admin/crawler/blacklist_cagi.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-2.distsn.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Spam
-2hu.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-anitwitter.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-anitwitter.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-ap.torlipen.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-ap.uwu.st 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Harassment or abuse
-babymetal.party 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-baraag.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-beehub.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-blob.cat 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-bodybuilding.im 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-bofa.lol 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-bsd.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-carnal-gabhub.protohype.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-civiq.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-cofe.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-comm.network 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-community.halle-leaks.de 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-community.highlandarrow.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-counter.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-cryzed.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-cyzed.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-daffodil-11.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Malicious site
-dev.civiq.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-develop.gab.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-dickshow.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-djitter.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-ediot.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f Fascism – Hatespeech
-ediot.socialsilence 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-ekrem.develop.gab.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-exited.eu 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-explosion.party 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Conspiracy theories
-fedichive.tk 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-feminism.lgbt 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-freefedifollowers.ga 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-freehold.earth 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-freespeechextremist.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-freespeech.firedragonstudios.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-freespeech.host 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-freevoice.space 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f Fascism – Hatespeech
-freezepeach.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gab.ai 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gabble.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gab.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gabfed.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gab.io 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gab.polaris-1.work 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gab.protohype.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gab.sleek.eu 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gameliberty.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-gasthe.lgbt 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gnusocial.no 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-goldandblack.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gorf.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f Fascism – Hatespeech
-gorf.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-gs.archae.me 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gs.kawa-kun.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gs.mon5t3r.info 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-gs.smuglo.li 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-hakui.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-homura.space 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Harassment or abuse
-ika.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-impeccable.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-inditoot.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-jabb.in 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Conspiracy theories
-juche.town 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-karolat.press 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-kawaiistu.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-kawen.space 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-kazvam.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-kipper.im 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-kiwifarms.cc 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-kneegrows.top 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-kowai.youkai.town 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-kyot.me 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-liberdon.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-libertarianism.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-libre.tube 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-loli.estate 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-lolis.world 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-manx.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-mastodon.loliandstuff.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-mastodon.starrevolution.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-mast.wholemars.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-melalandia.tk 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-me.nooruul.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-mobile.co 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-neckbeard.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-neenster.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-newjack.city 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Spam
-niu.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-noagendasocial.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f Fascism – Hatespeech
-not-develop.gab.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-not.phrack.fyi 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Conspiracy theories
-npf.mlpol.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-pawoo.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-pleroma.cucked.me 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-pleroma.rareome.ga 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Malicious site
-pleroma.soykaf.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-pleroma.wolfie.pw 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-pleroma.yorha.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Harassment or abuse
-pleville.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-pl.smuglo.li 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-porntoot.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-preteen.biz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-preteengirls.bi 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-preteengirls.biz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-pridelands.io 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-qoto.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-quey.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-quitter.pw 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-quodverum.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-rainbowdash.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-rapefeminists.network 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-sealion.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-shitasstits.life 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-shitposter.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-social.allthefallen.ninja 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-social.au2pb.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-social.guizzyordi.info 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-social.heldscal.la 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-social.hidamari.blue 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-social.homunyan.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-social.i2p.rocks 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-social.imirhil.fr 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-social.louisoft01.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Conspiracy theories
-social.lucci.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Conspiracy theories
-social.quodverum.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-social.raptorengineering.io 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Advertisement
-social.sunshinegardens.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Harassment or abuse
-social.super-niche.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-social.targaryen.house 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f Fascism – Hatespeech
-social.wiuwiu.de 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-socnet.supes.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-spinster.dev 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-spinster.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-sunshinegardens.org 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Harassment or abuse
-thechad.zone 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-the.hedgehoghunter.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-toot.love 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Bad Moderation
-unsafe.space 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f Fascism – Hatespeech
-vampire.estate 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-video.halle-leaks.de 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f
-vipgirlfriend.xxx 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Unflagged porn
-voluntaryism.club 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-wagesofsinisdeath.com 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-waifu.social 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-warc.space 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-weeaboo.space 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-weedis.life 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f
-wogan.im 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-woofer.alfter.us 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
-wrongthink.net 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 0 f f Fascism – Hatespeech
-wxw.moe 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-yiff.rocks 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Harassment or abuse
-youkai.town 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Pedo – Loli
-zerohack.xyz 2019-12-11 18:44:05.111111 2019-12-11 18:44:06.710862 1 f f Fascism – Hatespeech
diff --git a/web/admin/crawler/crawler.php b/web/admin/crawler/crawler.php
index f51b933..59b9c74 100755
--- a/web/admin/crawler/crawler.php
+++ b/web/admin/crawler/crawler.php
@@ -18,118 +18,38 @@
define('N',"\n");
-$inifp=null;
+declare(ticks=1);
+pcntl_signal(SIGTERM,'signalHandler');// Termination ('kill' was called)
+pcntl_signal(SIGHUP,'signalHandler');// Terminal log-out
+pcntl_signal(SIGINT,'signalHandler');// Interrupted (Ctrl-C is pressed)
+function signalHandler($signal) {
+ global $link, $logf, $jsonf;
+ lecho(N.'Sono stato interrotto.'.N);
+ if ($link) {
+ lecho('La connessione MySQL è aperta, la chiudo.'.N);
+ mysqli_close($link);
+ }
+ if ($jsonf) {
+ echo('Il file di dump json è aperto, lo chiudo.'.N);
+ fwrite($jsonf,'"Fine?": true'.N.'}'.N);
+ fclose($jsonf);
+ }
+ if ($logf) {
+ echo('Il file di log è aperto, lo chiudo.'.N);
+ fclose($logf);
+ }
+ exit(2);
+}
$opts=array(
- 'excludeafter'=>60*60*24*30,
- 'startinstancesfp'=>null,
- 'loadbiglist'=>true,
- 'onlinecheck'=>true,
- 'timeout'=>5,
- 'biglistfp'=>null,
- 'prodlistfp'=>null,
- 'blacklists'=>array(),
- 'whitelists'=>array()
+ 'timeout'=>3,
+ 'log'=>true,
+ 'jsonfp'=>'instances.json',
+ 'jsonwrite'=>true,
+ 'jsonread'=>false
);
-$help='DESCRIZIONE
- Questo script parte da una selezione di istanze Mastodon («istanze
- di partenza»), ciascuna con una relativa lista di istanze da essa
- bloccate (che può anche essere omessa), e genera/aggiorna due liste:
- una che conterrà i dati di tutte le istanze di partenza e delle istanze
- ad esse note (comprese quelle bloccate, escluse soltanto quelle che non
- rispondono da un lasso di tempo impostabile), e una che conterrà solo
- le istanze non bloccate, la cui piattaforma è mastodon, che danno
- possibilità di iscrizione di nuovi utenti, il cui numero di utenti
- è compreso tra 11 e 30000, che conoscono almeno altre 500 istanze,
- che hanno avuto almeno 10 utenti attivi nell\'ultimo mese o, se questo
- dato non è disponibile, la cui media di toot per utente è maggiore
- o uguale a 10.
-SINTASSI
- crawler.php -i | -s -b -p [altre opzioni]
-OPZIONI
- -i, --inifp
- Imposta un file di configurazione da cui leggere le opzioni.
- Il formato di questo file è semplice: una opzione per riga in formato
- =, dove «opzione» è una qualsiasi tra le opzioni
- descritte qui nel suo formato lungo, tranne «inifp» e «help».
- Esempio: «startinstancesfp=startinstances.txt».
- Il file di configurazione può non contenere tutte le opzioni
- disponibili.
- Nota bene: tutte le opzioni impostate da riga di comando, che siano
- specificate prima o dopo questa, hanno la precedenza su quelle
- definite nel file di configurazione.
- -s, --startinstancesfp
- DEVE essere specificata.
- Imposta il file da cui leggere le istanze di partenza e le relative
- liste di istanze sospese-silenziate.
- Il formato del file è questo: per ogni riga:
- |[uri della relativa lista di istanze
- bloccate]
- Ogni riga vuota o che cominci con il carattere «#» sarà ignorata.
- Il formato del file delle istanze bloccate è questo: per ogni riga:
- ||||
-
- Esempio di : «2019-12-11 18:44:06.710862»
- : «0» per silenziata, «1» per sospesa, «2» per "solo
- file media e rapporti".
- -b, --biglistfp
- DEVE essere specificata.
- Imposta il file da cui leggere le istanze già testate in passato
- (se il file esiste e non è specificata l’opzione «-d», vedi sotto)
- e in cui scrivere tutti i dati recuperabili delle istanze testate.
- -p, --prodlistfp
- DEVE essere specificata.
- Imposta il file da cui leggere (se esiste) e in cui scrivere i dati
- relativi alle istanze corrispondenti ai criteri di selezione descritti
- nel paragrafo «DESCRIZIONE».
- -B, --blacklistfp
- Imposta un eventuale file di istanze bloccate aggiuntivo. Per il
- formato di questi file vedi sopra il paragrafo relativo nella
- descrizione dell\'opzione «-s, --startinstancesfp». Questa opzione può
- essere utilizzata più volte per specificare più file di istanze
- bloccate. Nel file di configurazione ha un formato particolare:
- «blacklistfp=file1[,file2[,file3[...]]]».
- -w, --whitelistfp
- Imposta un eventuale file di istanze da non scartare mai, nemmeno
- se fanno parte di una delle blacklist utilizzato o non corrispondono
- ai criteri di filtraggio. Il formato di questi file è semplice:
- un dominio per riga (le righe vuote o che cominciano con il carattere
- «#» vengono ignorate. Questa opzione può essere utilizzata più volte
- per specificare più whitelist. Nel file di configurazione
- ha un formato particolare: «whitelistfp=file1[,file2[,file3[...]]]».
- -t, --timeout
- Imposta il timeout delle richieste http(s) in secondi.
- DEFAULT: '.$opts['timeout'].' secondi.
- -e, --excludeafter
- Imposta il lasso di tempo dopo il quale un’istanza che non risponde
- viene eliminata dal listone di tutte le istanze testate.
- «tempo» deve essere specificato come un numero, seguito eventualmente
- da un carattere che ne indica l’unità di misura: «s» o nessun
- carattere per secondi, «m» per minuti, «o» per ore, «g» per giorni,
- «S» per settimane, «M» per mesi (30 giorni), «A» per anni.
- DEFAULT: 1 mese.
- -l, --loadbiglist
- Dice al programma se caricare o meno il listone delle istanze già
- testate in passato.
- DEFAULT: «si».
- -c, --onlinecheck
- Dice al programma se interrogare o meno le istanze note.
- Se impostato a «no» forza a «si» «loadbiglist» (vedi opzione
- precedente).
- DEFAULT: «si».
- -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 for details.'.N;
-
-function mexit($msg,$code) {
- echo($msg);
- exit($code);
-}
+use function mysqli_real_escape_string as myesc;
function tosec($str) {
if (preg_match('/^([0-9]+)([smogSMA]?)/',$str,$buf)===1) {
@@ -162,441 +82,377 @@ function tosec($str) {
}
}
-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];
+function mexit($msg,$code,$closemy=false) {
+ global $link;
+ lecho($msg);
+ if ($closemy)
+ mysqli_close($link);
+ if ($logf)
+ fclose($logf);
+ exit($code);
+}
+
+function lecho($msg,$logonly=false) {
+ global $opts, $logf;
+ if (!$logonly)
+ echo($msg);
+ if ($opts['log'])
+ fwrite($logf,$msg);
+}
+
+$logfp='crawler.log';
+if ($opts['log']) {
+ $logf=@fopen(__DIR__.'/'.$logfp,'w')
+ or mexit('Non ho potuto aprire in scrittura il file di log «'.$logfp.'».',1);
+}
+
+$inifp='../sec/mastostartadmin.ini';
+$iniarr=parse_ini_file($inifp)
+ or mexit('Impossibile aprire il file di configurazione «'.$inifp.'»'.N,1);
+$link=mysqli_connect($iniarr['db_host'],$iniarr['db_admin_name'],$iniarr['db_admin_password'],$iniarr['db_name'],$iniarr['db_port'],$iniarr['db_socket'])
+ or mexit(mysqli_error($link).N,1);
+mysqli_set_charset($link,'utf8');
+
+$contextopts=array(
+ 'http'=>array(
+ 'timeout'=>$opts['timeout']
+ ),
+ 'socket'=>array(
+ 'tcp_nodelay'=>true
+ )
+);
+$context=stream_context_create($contextopts);
+
+$blacklist=array();
+lecho('Carico la blacklist dal database...'.N);
+$res=mysqli_query($link,'SELECT * FROM Blacklist')
+ or mexit(mysqli_error($link).N,3,true);
+lecho(mysqli_num_rows($res).' istanze nella blacklist.'.N);
+while($row=mysqli_fetch_assoc($res)) {
+ $blacklist[$row['Domain']]=$row;
+}
+
+function pgdatetomy($pgdate) {
+ if (preg_match('/^(\d+)-(\d+)-(\d+)[ T]{1}(\d+):(\d+):(\d+)\.(\d+)Z?$/',$pgdate,$buf)===1) {
+ return(mktime($buf[4],$buf[5],$buf[6],$buf[2],$buf[3],$buf[1])+floatval('0.'.$buf[7]));
+ } else {
+ return(false);
}
}
-if (!is_null($inifp)) {
- $buf=@parse_ini_file($inifp);
+function blpgdumplinetomy($line) {
+ $truefalse=array('f'=>0,'t'=>1);
+ $row=explode("\t",$line);
+ $row=array('Domain'=>$row[0],
+ 'CreatedAt'=>pgdatetomy($row[1]),
+ 'ModifiedAt'=>pgdatetomy($row[2]),
+ 'Severity'=>$row[3],
+ 'RejectMedia'=>$truefalse[$row[4]],
+ 'RejectReports'=>$truefalse[$row[5]],
+ 'PublicComment'=>$row[6]);
+ return($row);
+}
+
+$blacklistnew=array();
+$insts=array();
+lecho('Carico le istanze di partenza...'.N);
+$res=mysqli_query($link,'SELECT Domain FROM StartNodes')
+ or mexit(mysqli_error($link).N,3,true);
+lecho(mysqli_num_rows($res).' istanze di partenza.'.N);
+while($row=mysqli_fetch_assoc($res)) {
+ $insts[$row['Domain']]=null;
+ lecho('Recupero la lista delle istanze note a «'.$row['Domain'].'» ... ');
+ $buf=@file_get_contents('https://'.$row['Domain'].'/api/v1/instance/peers',false,$context);
if ($buf!==false) {
- foreach ($buf as $key=>$val) {
- if (array_key_exists($key,$opts)) {
- if ($key=='excludeafter') {
- $opts['excludeafter']=tosec($val);
- if ($opts['excludeafter']===false)
- mexit('L’opzione «excludeafter» specificata in «'.$inifp.'» non è in un formato corretto (usa «-h» per vedere la guida).'.N,1);
- } elseif ($key=='blacklists') {
- $opts['blacklists']=explode(',',$val);
- } elseif ($key=='whitelists') {
- $opts['whitelists']=explode(',',$val);
- } else {
- $opts[$key]=$val;
- }
- } else {
- echo('Attenzione: l’opzione «'.$key.'» in «'.$inifp.'» è sconosciuta e sarà ignorata.'.N);
+ lecho('OK :-)'.N);
+ $peers=json_decode($buf,true);
+ foreach ($peers as $pdom) {
+ if (!array_key_exists($pdom,$insts) && strlen($pdom)<=64) {
+ $insts[$pdom]=null;
}
}
} else {
- mexit('Attenzione: non ho potuto leggere la configurazione dal file «'.$inifp.'».'.N,1);
+ lecho('ERRORE :-('.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)
- $i++;
- $opts['excludeafter']=tosec($argv[$i]);
- if ($opts['excludeafter']===false)
- mexit('Opzione «'.$argv[$i].'»: formato non corretto (usa «-h» per vedere la guida).'.N,1);
- 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 '--prodlistfp':
- 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['prodlistfp']=$argv[$i];
- break;
- case '-s':
- case '--startinstancesfp':
- 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['startinstancesfp']=$argv[$i];
- break;
- case '-B':
- case '--blacklistfp':
- 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['blacklists'][]=$argv[$i];
- break;
- case '-w':
- case '--whitelistfp':
- 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['whitelists'][]=$argv[$i];
- break;
- case '-l':
- case '--loadbiglist':
- if ($i+1>=$argc || ($argv[$i+1]!='si' && $argv[$i+1]!='no'))
- mexit('L’opzione «'.$argv[$i].'» richiede un parametro («si/no») (usa «-h» per vedere la guida).'.N,1);
- $i++;
- $opts['loadbiglist']=true;
- if ($argv[$i]=='no') $opts['loadbiglist']=false;
- break;
- case '-c':
- case '--onlinecheck':
- if ($i+1>=$argc || ($argv[$i+1]!='si' && $argv[$i+1]!='no'))
- mexit('L’opzione «'.$argv[$i].'» richiede un parametro («si/no») (usa «-h» per vedere la guida).'.N,1);
- $i++;
- $opts['onlinecheck']=true;
- if ($argv[$i]=='no') $opts['onlinecheck']=false;
- 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);
- }
-}
-
-$buf=null;
-if (is_null($opts['startinstancesfp']))
- $buf.='- Non hai specificato il file delle istanze di partenza («-s/--startinstancesfp»)'.N;
-if (is_null($opts['biglistfp']))
- $buf.='- Non hai specificato il file da cui leggere e in cui salvare i dati di tutte le istanze testate («-b/--biglistfp»)'.N;
-if (is_null($opts['prodlistfp']))
- $buf.='- Non hai specificato il file da cui leggere e in cui salvare i dati di tutte le istanze testate che corrispondono ai criteri di selezione («-p/--prodlistfp»)'.N;
-if (!is_null($buf))
- mexit('ERRORI'.N.$buf.'Usa «-h/--help» per leggere la guida.'.N,1);
-
-if (!$opts['onlinecheck'])
- $opts['loadbiglist']=true;
-
-$biglist=array();
-$ibiglistc=0;
-if ($opts['loadbiglist']) {
- 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);
- $ibiglistc=count($biglist);
- } else {
- echo('ERRORE :-('.N);
- }
- }
-}
-
-$blinstances=array();
-$wlinstances=array();
-
-function loadblacklist($bluri) {
- global $blinstances, $opts;
- $context=stream_context_create(array('http'=>array('timeout'=>$opts['timeout'])));
- $f=@fopen($bluri,'r',false,$context);
- if ($f!==false) {
- $i=0;
- while (!feof($f)) {
- $lin=fgets($f);
-//bsd.moe|2019-12-11 18:44:06.710862|1|https://mastodon.bida.im/@Ca_Gi/101270762003908554
- if (preg_match('/^([^#\|]{1}[^\|]+)\|{1}([^\|]+)\|{1}([012]{1})\|{1}(.*)$/',$lin,$buf)===1 && !in_array($buf[1],$blinstances) ) {
- $i++;
- $blinstances[]=$buf[1];
- }
- }
- fclose($f);
- echo('OK :-) (+'.$i.' istanze bloccate caricate; totale: '.count($blinstances).')'.N);
- } else {
- mexit('ERRORE :-('.N,1);
- }
-}
-
-$startinstances=array();
-echo('Carico il file delle istanze di partenza («'.$opts['startinstancesfp'].'») ... ');
-$buf=@file_get_contents($opts['startinstancesfp']);
-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;
- $startinstances[$kv[0]]=$kv[1];
- }
- }
-} else {
- mexit(N.'Non ho potuto caricare il file delle istanze di partenza «'.$opts['startinstancesfp'].'», muoio.'.N,1);
-}
-if (count($startinstances)<1)
- mexit('Il file delle istanze di partenza «'.$opts['startinstancesfp'].'» non contiene alcuna voce, muoio.'.N,1);
-
-foreach ($startinstances as $dom=>$bluri) {
- if (!is_null($bluri)) {
- echo('Recupero la lista delle istanze bloccate da «'.$dom.'» («'.$bluri.'») ... ');
- loadblacklist($bluri);
- } else {
- echo('NON recupero la lista delle istanze bloccate da «'.$dom.'»: la uri della stessa non è definita.'.N);
- }
-}
-foreach ($opts['blacklists'] as $bluri) {
- echo('Carico la lista delle istanze bloccate dall\'URI «'.$bluri.'» ... ');
- loadblacklist($bluri);
-}
-sort($blinstances);
-echo(count($blinstances).' istanze bloccate.'.N);
-
-foreach ($opts['whitelists'] as $wluri) {
- echo('Carico la whitelist delle istanze dall\'URI «'.$wluri.'» ... ');
- $buf=@file_get_contents($wluri);
+ lecho('Recupero la blacklist di «'.$row['Domain'].'» ... ');
+ $buf=@file_get_contents('https://'.$row['Domain'].'/domain_blocks.txt',false,$context);
if ($buf!==false) {
- echo('OK :-)'.N);
+ lecho('OK :-)'.N);
$buf=explode(N,$buf);
- foreach ($buf as $val) {
- if ($val!='' && $val[0]!='#' && !in_array($val,$wlinstances))
- $wlinstances[]=$val;
+ foreach ($buf as $line) {
+ if (preg_match('/(^#.*$)|(^\s*$)/',$line)===0) {
+ $brow=blpgdumplinetomy($line);
+ if (!array_key_exists($brow['Domain'],$blacklist)) {
+ $blacklistnew[$brow['Domain']]=$brow;
+ }
+ $blacklist[$brow['Domain']]=$brow;
+ }
}
} else {
- mexit(N.'Non ho potuto caricare la whitelist delle istanze «'.$wluri.'», muoio.'.N,1);
+ lecho('ERRORE :-('.N);
}
}
-sort($wlinstances);
-echo(count($wlinstances).' istanze whitelistate.'.N);
+//lecho('Carico le istanze note dal DB e aggiungo alla lista di quelle da controllare quelle che non ci sono già.'.N);
+$res=mysqli_query($link,'SELECT URI FROM Instances')
+ or mexit(mysqli_error($link).N,3,true);
+while($row=mysqli_fetch_assoc($res)) {
+ if (!array_key_exists($row['URI'],$insts))
+ $insts[$row['URI']]=null;
+}
+ksort($insts);
+ksort($blacklist);
+ksort($blacklistnew);
+lecho('Istanze recuperate: '.count($insts).N);
+lecho('Istanze blacklistate: '.count($blacklist).', di cui '.count($blacklistnew).' nuove da aggiungere al DB.'.N);
-if ($opts['onlinecheck']) {
+foreach ($blacklistnew as $row) {
+ foreach($row as $key=>$val)
+ $row[$key]=myesc($link,$val);
+ mysqli_query($link,'INSERT INTO Blacklist (ID, Domain, CreatedAt, ModifiedAt, Severity, RejectMedia, RejectReports, PrivateComment, PublicComment) VALUES (NULL, \''.$row['Domain'].'\', \''.$row['CreatedAt'].'\', \''.$row['ModifiedAt'].'\', \''.$row['Severity'].'\', \''.$row['RejectMedia'].'\', \''.$row['RejectReports'].'\', NULL, \''.$row['PublicComment'].'\')')
+ or mexit(mysqli_error($link).N,3,true);
+}
- $context=stream_context_create(array('http'=>array('timeout'=>$opts['timeout'])));
+//INSERT INTO `Instances` (`ID`, `New`, `Chosen`, `Visible`, `BlackListed`, `URI`, `Title`, `ShortDesc`, `LongDesc`, `OurDesc`, `PlaceID`, `Email`, `Software`, `Version`, `UserCount`, `StatusCount`, `DomainCount`, `ActiveUsersMonth`, `ActiveUsersHalfYear`, `Thumb`, `RegOpen`, `RegReqApproval`, `MaxTootChars`, `AdmAccount`, `AdmDisplayName`, `AdmCreatedAt`, `AdmNote`, `AdmURL`, `AdmAvatar`, `AdmHeader`) VALUES (NULL, '1', '0', '0', '0', 'pantagruel.dnsup.net', 'Pantagruel', 'Descrizione breve', 'Descrizione lunga', 'Istanza molto carina senza soffitto, senza cucina', '1', 'Graume ', 'mastodon', '3.0.1', '2', '12', '345', '5', '10', 'http://www.iedm.it', '1', '0', '540', 'admin', 'Admin', '2019-12-11', 'Note \'admin\'', 'https://rame.altervista.org', 'http://www.iedm.it', 'http://www.iedm.it');
- foreach ($startinstances as $dom=>$bluri) {
- if (!array_key_exists($dom,$biglist))
- $biglist[$dom]=null;
- 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 (!array_key_exists($pdom,$biglist)) {
- $biglist[$pdom]=null;
- }
- }
- } else {
- echo('ERRORE :-('.N);
- }
+function b2i($bool) {
+ if ($bool)
+ return(1);
+ else
+ return(0);
+}
+
+//array key exists and value is not null
+function akeavinn($key,&$arr) {
+ if (array_key_exists($key,$arr) && !is_null($arr[$key]))
+ return(true);
+ else
+ return(false);
+}
+
+function nempty($str) {
+ if (preg_match('/^\s*$/',$str)===1)
+ return(null);
+ else
+ return($str);
+}
+
+function subarim($glue,$key,&$arr) {
+ $str='';
+ $i=1;
+ $carr=count($arr);
+ foreach ($arr as $inarr) {
+ $str.=$inarr[$key];
+ if ($i<$carr)
+ $str.=$glue;
+ $i++;
}
- ksort($biglist);
- $diff=count($biglist)-$ibiglistc;
- if ($diff>=0) $diff='+'.$diff;
- echo('Totale istanze note: '.count($biglist).' ('.$diff.' rispetto all\'ultima volta).'.N);
+ return($str);
}
-$prodlist=array();
-$iprodlistc=0;
-$buf=@file_get_contents($opts['prodlistfp']);
-if ($buf!==false) {
- $prodlist=json_decode($buf,true);
- $iprodlistc=count($prodlist);
+function notify($msg,$sev) {
+ global $link;
+ mysqli_query($link,'INSERT INTO Notifications (ID, Notification, Severity, Microtime) VALUES (NULL, \''.myesc($link,$msg).'\', '.$sev.', '.microtime().')')
+ or mexit(mysqli_error($link).N,3,true);
}
-$newbiglist=array();
+/*
+ * Nodeinfo ('https://'.$dom.'/nodeinfo/2.0') è stato aggiunto nella 3.0.0
+ * Trends ('https://'.$dom.'/api/v1/trends') è stato aggiunto nella 3.0.0
+ * Activity ('https://'.$dom.'/api/v1/instance/activity') è stato aggiunto nella 2.1.2
+*/
+
+if ($opts['jsonwrite']) {
+ $jsonf=@fopen(__DIR__.'/'.$opts['jsonfp'],'w')
+ or mexit('Non ho potuto aprire in scrittura il file di dump delle info json «'.$opts['jsonfp'].'».',1);
+ fwrite($jsonf,'{'.N);
+}
+$cinsts=count($insts);
$i=0;
-$biglistc=count($biglist);
-foreach ($biglist as $dom=>$oinfo) {
+$ok=0;
+foreach ($insts as $dom=>$row) {
$i++;
- echo('~~~~~~'.N);
- if ($opts['onlinecheck']) {
-
- echo('Recupero le informazioni su «'.$dom.'» ('.$i.'/'.$biglistc.' - '.round(100/$biglistc*$i).'%)'.N);
-
- echo('Recupero le informazioni Nodeinfo ... ');
- $ninfo=null;
- $buf=@file_get_contents('https://'.$dom.'/nodeinfo/2.0',false,$context);
- if ($buf!==false) {
- echo('OK :-)'.N);
- $ninfo=json_decode($buf,true);
- } else {
- echo('ERRORE :-('.N);
- }
-
- echo('Recupero le informazioni API sull\'attività dell\'istanza ... ');
- $activity=null;
- $buf=@file_get_contents('https://'.$dom.'/api/v1/instance/activity',false,$context);
- if ($buf!==false) {
- echo('OK :-)'.N);
- $activity=json_decode($buf,true);
- } else {
- echo('ERRORE :-('.N);
- }
-
- echo('Recupero le informazioni API sull\'istanza ... ');
- $info=null;
- $buf=@file_get_contents('https://'.$dom.'/api/v1/instance',false,$context);
- if ($buf!==false) {
- echo('OK :-)'.N);
- $info=json_decode($buf,true);
- if (!is_null($oinfo) && array_key_exists('X-Checks',$oinfo))
- $info['X-Checks']=$oinfo['X-Checks'];
- $info['X-Checks'][]=array('time'=>time(),'ok'=>true);
- if (!is_null($ninfo)) {
- if (array_key_exists('usage',$ninfo) && array_key_exists('users',$ninfo['usage'])) {
- if (array_key_exists('activeMonth',$ninfo['usage']['users']))
- $info['X-ActiveUsersPerMonth']=$ninfo['usage']['users']['activeMonth'];
- if (array_key_exists('activeHalfyear',$ninfo['usage']['users']))
- $info['X-ActiveUsersPerHalfYear']=$ninfo['usage']['users']['activeHalfyear'];
- }
- if (array_key_exists('software',$ninfo)) {
- if (array_key_exists('name',$ninfo['software']))
- $info['X-Software']=$ninfo['software']['name'];
- if (array_key_exists('version',$ninfo['software']))
- $info['X-Version']=$ninfo['software']['version'];
+ $info=null;
+ lecho('~~~~~~~~~~~~~~~'.N);
+ lecho('Provo a recuperare info su «'.$dom.'» ['.$i.'/'.$cinsts.' ('.$ok.' OK) - '.round(100/$cinsts*$i).'%]'.N);
+ lecho('Provo a recuperare le informazioni API sull’istanza ... ');
+ $buf=@file_get_contents('https://'.$dom.'/api/v1/instance',false,$context);
+ if ($buf!==false) {
+ $ok++;
+ lecho('OK :-)'.N);
+ $info=json_decode($buf,true);
+ if (array_key_exists('version',$info)) {
+ if ($info['version']>='2.1.2') {
+ lecho('Provo a recuperare le informazioni API sull’attività dell’istanza ... ');
+ $buf=@file_get_contents('https://'.$dom.'/api/v1/instance/activity',false,$context);
+ if ($buf!==false) {
+ lecho('OK :-)'.N);
+ $info['x-activity']=json_decode($buf,true);
+ } else {
+ lecho('ERRORE :-('.N);
}
}
- if (!is_null($activity))
- $info['X-Activity']=$activity;
- $newbiglist[$dom]=$info;
- } else {
- echo('ERRORE :-( ... ');
- $lastokk=null;
- if (!is_null($oinfo) && array_key_exists('X-Checks',$oinfo)) {
- foreach ($oinfo['X-Checks'] as $key=>$val)
- if ($val['ok']) $lastokk=$key;
+ if ($info['version']>='3.0.0') {
+ lecho('Provo a recuperare le informazioni Nodeinfo sull’istanza ... ');
+ $buf=@file_get_contents('https://'.$dom.'/nodeinfo/2.0',false,$context);
+ if ($buf!==false) {
+ lecho('OK :-)'.N);
+ $info['x-nodeinfo']=json_decode($buf,true);
+ } else {
+ lecho('ERRORE :-('.N);
+ }
+ lecho('Provo a recuperare le informazioni API sui trends dell’istanza ... ');
+ $buf=@file_get_contents('https://'.$dom.'/api/v1/trends',false,$context);
+ if ($buf!==false) {
+ lecho('OK :-)'.N);
+ $info['x-trends']=json_decode($buf,true);
+ } else {
+ lecho('ERRORE :-('.N);
+ }
}
- if (is_null($oinfo) || is_null($lastokk) || time()-$oinfo['X-Checks'][$lastokk]['time']<=$opts['excludeafter']) {
- echo('ma riproveremo...'.N);
- $oinfo['X-Checks'][]=array('time'=>time(),'ok'=>false);
- $newbiglist[$dom]=$oinfo;
- } else {
- echo('e non riproveremo...'.N);
- $oinfo=null;
- }
- $info=$oinfo;
}
} else {
- $info=$oinfo;
+ lecho('ERRORE :-('.N);
}
- $whynot=array();
- if (array_key_exists('uri',$info)) {
- if (!in_array($dom,$wlinstances)) {
- if (in_array($dom,$blinstances))
- $whynot[]='Istanza blacklistata';
- if (array_key_exists('X-Software',$info) && !in_array($info['X-Software'],array('mastodon','corgidon')))
- $whynot[]='Il software non è Mastodon (ma '.$info['X-Software'].')';
- if (!array_key_exists('registrations',$info))
- $whynot[]='Stato delle registrazioni non disponibile';
- elseif ($info['registrations']==false)
- $whynot[]='Registrazioni chiuse';
- if (!array_key_exists('stats',$info)) {
- $whynot[]='Stats non disponibili';
- } else {
- if (!array_key_exists('user_count',$info['stats']))
- $whynot[]='Numero utenti non disponibile';
- elseif ($info['stats']['user_count']<10 || $info['stats']['user_count']>30000)
- $whynot[]='Numero utenti ('.$info['stats']['user_count'].') non compreso tra 10 e 30000';
- if (!array_key_exists('domain_count',$info['stats']))
- $whynot[]='Numero istanze conosciute non disponibile';
- elseif ($info['stats']['domain_count']<500)
- $whynot[]='Numero istanze conosciute minore di 500';
- /* if (!array_key_exists('status_count',$info['stats']))
- $whynot[]='Numero di toots non disponibile';
- elseif ($info['stats']['status_count']/$info['stats']['user_count']<10)
- $whynot[]='Media dei toots per utente minore di 10';*/
+ if (!is_null($info) && akeavinn('uri',$info) && !is_null(nempty($info['uri']))) {
+ lecho(json_encode($info,JSON_PRETTY_PRINT).N,true);
+ if ($opts['jsonwrite'])
+ fwrite($jsonf,'"'.$info['uri'].'": '.json_encode($info,JSON_PRETTY_PRINT).','.N);
+//INSERT INTO `Instances` (`ID`, `New`, `Chosen`, `Visible`, `BlackListed`, `URI`, `Title`, `ShortDesc`, `LongDesc`, `OurDesc`, `PlaceID`, `Email`, `Software`, `Version`, `UserCount`, `StatusCount`, `DomainCount`, `ActiveUsersMonth`, `ActiveUsersHalfYear`, `Thumb`, `RegOpen`, `RegReqApproval`, `MaxTootChars`, `AdmAccount`, `AdmDisplayName`, `AdmCreatedAt`, `AdmNote`, `AdmURL`, `AdmAvatar`, `AdmHeader`) VALUES (NULL, '1', '0', '0', '0', 'pantagruel.dnsup.net', 'Pantagruel', 'Descrizione breve', 'Descrizione lunga', 'Istanza molto carina senza soffitto, senza cucina', '1', 'Graume ', 'mastodon', '3.0.1', '2', '12', '345', '5', '10', 'http://www.iedm.it', '1', '0', '540', 'admin', 'Admin', '2019-12-11', 'Note \'admin\'', 'https://rame.altervista.org', 'http://www.iedm.it', 'http://www.iedm.it');
+ $instrow=array('ID'=>null, 'New'=>0, 'Chosen'=>0, 'Visible'=>0, 'BlackListed'=>0, 'URI'=>null, 'Title'=>null, 'ShortDesc'=>null, 'LongDesc'=>null, 'OurDesc'=>null, 'PlaceID'=>null, 'Email'=>null, 'Software'=>null, 'Version'=>null, 'UserCount'=>null, 'StatusCount'=>null, 'DomainCount'=>null, 'ActiveUsersMonth'=>null, 'ActiveUsersHalfYear'=>null, 'Thumb'=>null, 'RegOpen'=>null, 'RegReqApproval'=>null, 'MaxTootChars'=>null, 'AdmAccount'=>null, 'AdmDisplayName'=>null, 'AdmCreatedAt'=>null, 'AdmNote'=>null, 'AdmURL'=>null, 'AdmAvatar'=>null, 'AdmHeader'=>null);
+ if (array_key_exists($info['uri'],$blacklist))
+ $instrow['BlackListed']=1;
+ $instrow['URI']=nempty($info['uri']);
+ if (akeavinn('title',$info))
+ $instrow['Title']=nempty($info['title']);
+ if (akeavinn('short_description',$info))
+ $instrow['ShortDesc']=nempty($info['short_description']);
+ if (akeavinn('description',$info))
+ $instrow['LongDesc']=nempty($info['description']);
+ if (akeavinn('email',$info))
+ $instrow['Email']=nempty($info['email']);
+ if (akeavinn('version',$info))
+ $instrow['Version']=nempty($info['version']);
+ if (akeavinn('stats',$info)) {
+ if (akeavinn('user_count',$info['stats']))
+ $instrow['UserCount']=$info['stats']['user_count'];
+ if (akeavinn('status_count',$info['stats']))
+ $instrow['StatusCount']=$info['stats']['status_count'];
+ if (akeavinn('domain_count',$info['stats']))
+ $instrow['DomainCount']=$info['stats']['domain_count'];
+ }
+ if (akeavinn('thumbnail',$info))
+ $instrow['Thumb']=nempty($info['thumbnail']);
+ if (akeavinn('max_toot_chars',$info))
+ $instrow['MaxTootChars']=$info['max_toot_chars'];
+ if (akeavinn('registrations',$info))
+ $instrow['RegOpen']=b2i($info['registrations']);
+ if (akeavinn('approval_required',$info))
+ $instrow['RegReqApproval']=b2i($info['approval_required']);
+ if (akeavinn('contact_account',$info)) {
+ if (akeavinn('acct',$info['contact_account']))
+ $instrow['AdmAccount']=nempty($info['contact_account']['acct']);
+ if (akeavinn('display_name',$info['contact_account']))
+ $instrow['AdmDisplayName']=nempty($info['contact_account']['display_name']);
+ if (akeavinn('created_at',$info['contact_account']))
+ $instrow['AdmCreatedAt']=pgdatetomy($info['contact_account']['created_at']);
+ if (akeavinn('note',$info['contact_account']))
+ $instrow['AdmNote']=nempty(strip_tags($info['contact_account']['note'],''));
+ if (akeavinn('url',$info['contact_account']))
+ $instrow['AdmURL']=nempty($info['contact_account']['url']);
+ if (akeavinn('avatar',$info['contact_account']))
+ $instrow['AdmAvatar']=nempty($info['contact_account']['avatar']);
+ if (akeavinn('header',$info['contact_account']))
+ $instrow['AdmHeader']=nempty($info['contact_account']['header']);
+ }
+ if (akeavinn('x-nodeinfo',$info)) {
+ if (akeavinn('software',$info['x-nodeinfo']) && akeavinn('name',$info['x-nodeinfo']['software']))
+ $instrow['Software']=nempty($info['x-nodeinfo']['software']['name']);
+ if (akeavinn('usage',$info['x-nodeinfo']) && akeavinn('users',$info['x-nodeinfo']['usage'])) {
+ if (akeavinn('activeMonth',$info['x-nodeinfo']['usage']['users']))
+ $instrow['ActiveUsersMonth']=$info['x-nodeinfo']['usage']['users']['activeMonth'];
+ if (akeavinn('activeHalfyear',$info['x-nodeinfo']['usage']['users']))
+ $instrow['ActiveUsersHalfYear']=$info['x-nodeinfo']['usage']['users']['activeHalfyear'];
}
- if (array_key_exists('X-ActiveUsersPerMonth',$info)) {
- if ($info['X-ActiveUsersPerMonth']<10)
- $whynot[]='Numero utenti attivi nell\'ultimo mese minore di 10';
- } elseif (array_key_exists('stats',$info) && array_key_exists('status_count',$info['stats']) && array_key_exists('user_count',$info['stats']) && $info['stats']['user_count']>0 && $info['stats']['status_count']/$info['stats']['user_count']<10) {
- $whynot[]='Media dei toots per utente minore di 10';
+ }
+ $res=mysqli_query($link,'SELECT * FROM Instances WHERE URI=\''.myesc($link,$instrow['URI']).'\'')
+ or mexit(mysqli_error($link).N,3,true);
+ if (mysqli_num_rows($res)>0) {
+ lecho('«'.$instrow['URI'].'» è già presente nel DB, la aggiorno...'.N);
+ $oldinstrow=mysqli_fetch_assoc($res);
+ $query='UPDATE Instances SET ';
+ foreach ($instrow as $field=>$value) {
+ if (!is_null($value))
+ $query.=$field.'=\''.myesc($link,$value).'\', ';
+ else
+ $query.=$field.'=\'NULL\', ';
}
- if (!array_key_exists('contact_account',$info) || is_null($info['contact_account'])) {
- $whynot[]='Informazioni sull\'account admin principale non disponibili';
- }/* else {
- if (!array_key_exists('created_at',$info['contact_account']))
- $whynot[]='Data di creazione dell\'account admin principale non disponibile';
- elseif (time()-strtotime($info['contact_account']['created_at'])<6*31*24*60*60)
- $whynot[]='L\'account admin principale risulta esser stato creato meno di 6 mesi fa';
+ $query=substr($query,0,-2).' WHERE Instances.ID='.$oldinstrow['ID'];
+ echo('QUERONA DI UPDATE: «'.$query.'».'.N);
+/* $res=mysql_query($link,'SELECT InstID, LangID, Pos, Code FROM InstLangs LEFT JOIN Languages ON Languages.ID=LangID WHERE InstID='.$oldinstrow['ID'].' ORDER BY Pos ASC')
+ or mexit(mysqli_error($link).N,3,true);
+ $oldinstlangs=array();
+ while ($row=mysql_fetch_assoc($res))
+ $oldinstlangs[]=$row;
+ if (akeavinn('languages',$info)) {
+ $instlangs=array();
+ $pos=0;
+ foreach ($info['languages'] as $lang) {
+ $res=mysqli_query($link,'SELECT * FROM Languages WHERE Code=\''.myesc($link,$lang).'\'')
+ or mexit(mysqli_error($link).N,3,true);
+ if (mysqli_num_rows($res)<1) {
+ mysqli_query($link,'INSERT INTO Languages (ID, Code, Name) VALUES (NULL, \''.myesc($link,$lang).'\', NULL)')
+ or mexit(mysqli_error($link).N,3,true);
+ $langid=mysqli_insert_id($link);
+ notify('L’aggiornamento dei dati relativi all’istanza «'.$info['URI'].'» ha aggiunto un codice lingua non ancora noto, «'.$lang.'», di cui non conosco il nome per esteso. Puoi editarlo qui.',1);
+ } else {
+ $row=mysqli_fetch_assoc($res);
+ $langid=$row['ID'];
+ }
+ $pos++;
+ $instlangs[]=array('InstID'=>$oldinstrow['ID'],'LangID'=>$langid,'Pos'=>$pos,'Code'=>$lang);
+ }
+ print_r($instlangs);
+ print_r($oldinstlangs);
+ if ($instlangs!=$oldinstlangs) {
+ notify('La lista delle lingue utilizzate dichiarate dall’istanza «'.$info['URI'].'» è cambiata da «'.subarim(', ','Code',$oldinstlangs).'» a «'.subarim(', ','Code',$oldinstlangs).'».',1);
+ mysqli_query($link,'DELETE FROM InstLangs WHERE InstID='.$oldinstrow['ID'])
+ or mexit(mysqli_error($link).N,3,true);
+ foreach ($instlangs as $row) {
+ mysqli_query($link,'INSERT INTO InstLangs (InstID, LangID, Pos) VALUES ('.$row['InstID'].', '.$row['LangID'].', '.$row['Pos'].')')
+ or mexit(mysqli_error($link).N,3,true);
+ }
+ }
}*/
} else {
- echo('«'.$dom.'» è whitelistata, la teniamo a prescindere.'.N);
- }
- } elseif (!array_key_exists($dom,$prodlist)) {
- $whynot[]='Info non disponibili, e l\'istanza non era già presente nella lista delle istanze occhei';
- }
- if (count($whynot)==0) {
- if (array_key_exists($dom,$prodlist)) {
- if (array_key_exists('short_description',$info) && (!array_key_exists('short_description',$prodlist[$dom]) || $prodlist[$dom]['short_description']!=$info['short_description'])) {
- $info['X-ShortDescriptionChanged']=true;
- $info['X-PrevShortDescription']=$prodlist[$dom]['short_description'];
- } else {
- $info['X-ShortDescriptionChanged']=false;
+ lecho('«'.$info['uri'].'» non è già presente nel DB, la aggiungo...'.N);
+ $instrow['New']=1;
+ $fields=array();
+ $values='';
+ foreach ($instrow as $field=>$value) {
+ $fields[]=$field;
+ if (!is_null($value))
+ $values.='\''.myesc($link,$value).'\', ';
+ else
+ $values.='NULL, ';
}
- if (array_key_exists('description',$info) && (!array_key_exists('description',$prodlist[$dom]) || $prodlist[$dom]['description']!=$info['description'])) {
- $info['X-DescriptionChanged']=true;
- $info['X-PrevDescription']=$prodlist[$dom]['description'];
- } else {
- $info['X-DescriptionChanged']=false;
- }
- echo('«'.$dom.'» era nella lista delle istanze occhei ed è stata AGGIORNATA! :-)'.N);
- if (array_key_exists('X-Show',$prodlist[$dom]))
- $info['X-Show']=$prodlist[$dom]['X-Show'];
- else
- $info['X-Show']=-1;
- } else {
- $info['X-ShortDescriptionChanged']=false;
- $info['X-DescriptionChanged']=false;
- $info['X-Show']=-1;
- echo('«'.$dom.'» non era nella lista delle istanze occhei ed è stata AGGIUNTA! :-)'.N);
+ $values=substr($values,0,-2);
+ $query='INSERT INTO Instances ('.implode(', ',$fields).') VALUES ('.$values.')';
+ echo('QUERONA DI INSERT: «'.$query.'»'.N);
}
- $prodlist[$dom]=$info;
- } else {
- if (array_key_exists($dom,$prodlist)) {
- unset($prodlist[$dom]);
- echo('«'.$dom.'» era nella lista delle istanze occhei ma è stata SCARTATA! :-('.N);
- } else {
- echo('«'.$dom.'» non era nella lista delle istanze occhei e NON CI È ENTRATA! :-('.N);
- }
- echo('Motivazioni: '.implode('; ',$whynot).'.'.N);
+// var_dump($instrow);
}
}
-echo('~~~~~~'.N);
+mysqli_close($link);
-if ($opts['onlinecheck']) {
- $json=json_encode($newbiglist,JSON_PRETTY_PRINT);
- file_put_contents($opts['biglistfp'],$json);
- $newbiglistc=count($newbiglist);
- $diff=$newbiglistc-$ibiglistc;
- if ($diff>=0) $diff='+'.$diff;
- echo('Totale istanze nella listona: '.$newbiglistc.' ('.$diff.' rispetto all\'ultima volta)'.N);
-} else {
- echo('Totale istanze nella listona: '.count($biglist).N);
+if ($opts['jsonwrite']) {
+ fwrite($jsonf,'"Fine?": true'.N.'}'.N);
+ fclose($jsonf);
}
-$json=json_encode($prodlist,JSON_PRETTY_PRINT);
-file_put_contents($opts['prodlistfp'],$json);
-$diff=count($prodlist)-$iprodlistc;
-if ($diff>=0) $diff='+'.$diff;
-echo('Totale istanze nella listina di quelle occhei: '.count($prodlist).' ('.$diff.' rispetto all\'ultima volta)'.N);
+
+if ($opts['log'])
+ fclose($logf);
+
+exit(0);
?>
diff --git a/web/admin/crawler/crawler_pant.ini b/web/admin/crawler/crawler_pant.ini
deleted file mode 100644
index 190070f..0000000
--- a/web/admin/crawler/crawler_pant.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-excludeafter=1M
-startinstancesfp=istanzesorelle_pant
-loadbiglist=true
-onlinecheck=true
-timeout=5
-biglistfp=biglist_pant.json
-prodlistfp=prodlist_pant.json
-blacklists=blacklist_cagi.txt
-whitelists=whitelist_sorellanza.txt
diff --git a/web/admin/crawler/crawler_sorellanza.ini b/web/admin/crawler/crawler_sorellanza.ini
deleted file mode 100644
index 9d82098..0000000
--- a/web/admin/crawler/crawler_sorellanza.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-excludeafter=1M
-startinstancesfp=istanzesorelle
-loadbiglist=true
-onlinecheck=true
-timeout=3
-biglistfp=biglist.json
-prodlistfp=prodlist.json
-blacklists=blacklist_cagi.txt
-whitelists=whitelist_sorellanza.txt
diff --git a/web/admin/crawler/istanzesorelle b/web/admin/crawler/istanzesorelle
deleted file mode 100644
index 06acaac..0000000
--- a/web/admin/crawler/istanzesorelle
+++ /dev/null
@@ -1,5 +0,0 @@
-mastodon.bida.im|blacklist_bida.txt
-mastodon.cisti.org|
-nebbia.fail|
-stereodon.social|
-snapj.saja.freemyip.com|
diff --git a/web/admin/crawler/istanzesorelle_pant b/web/admin/crawler/istanzesorelle_pant
deleted file mode 100644
index 8b56c12..0000000
--- a/web/admin/crawler/istanzesorelle_pant
+++ /dev/null
@@ -1 +0,0 @@
-pantagruel.dnsup.net|blacklist_bida.txt
diff --git a/web/admin/favicon.ico b/web/admin/favicon.ico
new file mode 100644
index 0000000..c03b1b9
Binary files /dev/null and b/web/admin/favicon.ico differ
diff --git a/web/admin/imgs/icona-180.png b/web/admin/imgs/icona-180.png
new file mode 100644
index 0000000..b4b0ed6
Binary files /dev/null and b/web/admin/imgs/icona-180.png differ
diff --git a/web/admin/imgs/icona-192.png b/web/admin/imgs/icona-192.png
new file mode 100644
index 0000000..a654000
Binary files /dev/null and b/web/admin/imgs/icona-192.png differ
diff --git a/web/admin/imgs/icona-32.png b/web/admin/imgs/icona-32.png
new file mode 100644
index 0000000..b9b903e
Binary files /dev/null and b/web/admin/imgs/icona-32.png differ
diff --git a/web/admin/imgs/icona-512.png b/web/admin/imgs/icona-512.png
new file mode 100644
index 0000000..9ad6300
Binary files /dev/null and b/web/admin/imgs/icona-512.png differ
diff --git a/web/admin/include/connuser.php b/web/admin/include/connuser.php
new file mode 100644
index 0000000..553b365
--- /dev/null
+++ b/web/admin/include/connuser.php
@@ -0,0 +1,10 @@
+Login.',true);
+$user=mysqli_fetch_assoc($res);
+
+?>
diff --git a/web/admin/include/glob.php b/web/admin/include/glob.php
new file mode 100644
index 0000000..af9f50c
--- /dev/null
+++ b/web/admin/include/glob.php
@@ -0,0 +1,10 @@
+
diff --git a/web/admin/include/menu.php b/web/admin/include/menu.php
new file mode 100644
index 0000000..c6927a5
--- /dev/null
+++ b/web/admin/include/menu.php
@@ -0,0 +1,52 @@
+array('liadd'=>null, 'href'=>'istanze.php', 'title'=>'Istanze', 'selected'=>false, 'submenu'=>
+ array(
+ 'aggiungi'=>array('liadd'=>'onclick="golang(\'en\')" onmouseover="this.style.cursor=\'pointer\'"', 'href'=>null, 'title'=>'English', 'selected'=>false, 'submenu'=>null),
+ 'italiano'=>array('liadd'=>'onclick="golang(\'it\')" onmouseover="this.style.cursor=\'pointer\'"', 'href'=>null, 'title'=>'Italiano', 'selected'=>false, 'submenu'=>null)
+ )
+ ),
+ 'boh'=>array('liadd'=>null, 'href'=>'#', 'title'=>'Non saprei', 'selected'=>false, 'submenu'=>null),
+ 'vedremo'=>array('liadd'=>null, 'href'=>'#', 'title'=>'Vedremo', 'selected'=>false, 'submenu'=>null),
+ 'forse'=>array('liadd'=>null, 'href'=>'#', 'title'=>'Forse', 'selected'=>false, 'submenu'=>null)
+);
+
+
+/*
+
+*/
+
+$menuout='';
+
+function buildmenu($menu) {
+ global $menuout;
+ foreach ($menu as $key=>$arr) {
+ $menuout.='
';
+ if (!is_null($arr['href']))
+ $menuout.=''.$arr['title'].'';
+ else
+ $menuout.=$arr['title'];
+ if (!is_null($arr['submenu'])) {
+// qui bisognerebbe aggiungere che a seconda del "livello" imposta class giusta: ula, oppure ulb per livello > 1
+ $menuout.=N.'