1
0
Fork 0

26 dicembre 2019

This commit is contained in:
pezcurrel 2019-12-26 21:57:36 +01:00
parent 9739349d33
commit 113d3090e7
39 changed files with 1193 additions and 727 deletions

View file

@ -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 <http://www.gnu.org/licenses/>.
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 ' ' )"

View file

@ -0,0 +1,38 @@
<?php
define('N',"\n");
$conffp='../.env.production';
$conf=array(
'DB_HOST'=>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);
?>

View file

@ -0,0 +1,2 @@
Order deny,allow
Deny from all

View file

@ -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

View file

@ -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

View file

@ -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 <file> | -s <file> -b <file> -p <file> [altre opzioni]
OPZIONI
-i, --inifp <file>
Imposta un file di configurazione da cui leggere le opzioni.
Il formato di questo file è semplice: una opzione per riga in formato
<opzione>=<valore>, 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 <file>
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 istanza di partenza>|[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:
|<uri della istanza bloccata>|<data del blocco>|<tipo di blocco>|
<motivazione pubblica del blocco>
Esempio di <data del blocco>: «2019-12-11 18:44:06.710862»
<tipo di blocco>: «0» per silenziata, «1» per sospesa, «2» per "solo
file media e rapporti".
-b, --biglistfp <file>
DEVE essere specificata.
Imposta il file da cui leggere le istanze già testate in passato
(se il file esiste e non è specificata lopzione «-, vedi sotto)
e in cui scrivere tutti i dati recuperabili delle istanze testate.
-p, --prodlistfp <file>
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 <secondi>
Imposta il timeout delle richieste http(s) in secondi.
DEFAULT: '.$opts['timeout'].' secondi.
-e, --excludeafter <tempo>
Imposta il lasso di tempo dopo il quale unistanza 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 lunità 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 <si|no>
Dice al programma se caricare o meno il listone delle istanze già
testate in passato.
DEFAULT: «si».
-c, --onlinecheck <si|no>
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 <http://www.gnu.org/licenses/> 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('Lopzione «'.$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('Lopzione «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: lopzione «'.$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('Lopzione «'.$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('Lopzione «'.$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('Lopzione «'.$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('Lopzione «'.$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('Lopzione «'.$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('Lopzione «'.$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('Lopzione «'.$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('Lopzione «'.$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 <graume@inventati.org>', '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 sullistanza ... ');
$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 sullattività dellistanza ... ');
$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 sullistanza ... ');
$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 dellistanza ... ');
$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 <graume@inventati.org>', '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'],'<a>'));
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('Laggiornamento dei dati relativi allistanza «<a href="editinst.php?id='.$oldinstrow['ID'].'">'.$info['URI'].'</a>» ha aggiunto un codice lingua non ancora noto, «'.$lang.'», di cui non conosco il nome per esteso. Puoi <a href="editlang.php?id='.$langid.'">editarlo qui</a>.',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 dallistanza «<a href="editinst.php?id='.$oldinstrow['ID'].'">'.$info['URI'].'</a>» è 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);
?>

View file

@ -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

View file

@ -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

View file

@ -1,5 +0,0 @@
mastodon.bida.im|blacklist_bida.txt
mastodon.cisti.org|
nebbia.fail|
stereodon.social|
snapj.saja.freemyip.com|

View file

@ -1 +0,0 @@
pantagruel.dnsup.net|blacklist_bida.txt

BIN
web/admin/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
web/admin/imgs/icona-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,10 @@
<?php
$iniarr=parse_ini_file('sec/marcovaldo.ini') or muoribene(_('Impossibile aprire il file di configurazione.'),false);
$link=mysqli_connect($iniarr['myhost'],$iniarr['myuser'],$iniarr['mypassword'],$iniarr['mydb']) or muoribene(_('Impossibile connettersi al database').': '.mysqli_connect_error().' ['.mysqli_connect_errno().']',false);
mysqli_set_charset($link,'utf8');
$res=mysqli_query($link,'SELECT * FROM Users WHERE ID='.$_SESSION['uid']) or muoribene(mysqli_error($link),true);
if (mysqli_num_rows($res)!=1) muoribene(_('Utente non esistente.').'<br><a href="index.php">Login</a>.',true);
$user=mysqli_fetch_assoc($res);
?>

View file

@ -0,0 +1,10 @@
<?php
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.
define('N',"\n");
$cjrand=rand(0,999999);
?>

View file

@ -0,0 +1,52 @@
<?php
$menu=array(
'istanze'=>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)
);
/*
<li><a href=".">Guide</a></li>
<li><a href="instances">Instances</a></li>
<li><a href="about">About us</a></li>
<li onmouseover="chulsh(this,true)" onmouseout="chulsh(this,false)">Language
<ul class="ula" onmouseover="ulsh(this,true)" onmouseout="ulsh(this,false)">
<li><a href="#">English</a></li>
<li><a href="#">Italiano</a></li>
</ul>
</li>
*/
$menuout='';
function buildmenu($menu) {
global $menuout;
foreach ($menu as $key=>$arr) {
$menuout.='<li';
if (!is_null($arr['liadd'])) $menuout.=' '.$arr['liadd'];
if (!is_null($arr['submenu'])) $menuout.=' onmouseover="chulsh(this,true)" onmouseout="chulsh(this,false)"';
if ($arr['selected']) $menuout.=' class="hil"';
$menuout.='>';
if (!is_null($arr['href']))
$menuout.='<a href="'.$arr['href'].'">'.$arr['title'].'</a>';
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.'<ul class="ula" onmouseover="ulsh(this,true)" onmouseout="ulsh(this,false)">'.N;
buildmenu($arr['submenu']);
$menuout.='</ul>'.N;
}
$menuout.='</li>'.N;
}
}
?>

View file

@ -0,0 +1,31 @@
<?php
function muoribene($msg,$close) {
global $mylink;
if ($close) mysqli_close($mylink);
echo('<!DOCTYPE HTML>
<html lang="it">
<head>
<title>Mastodon Startpage Admin - Errori</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="Mastodon Startpage Admin - Errori">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="icon" type="image/png" href="imgs/icona-32.png" sizes="32x32">
<link rel="icon" type="image/png" href="imgs/icona-192.png" sizes="192x192">
<link rel="icon" type="image/png" href="imgs/icona-512.png" sizes="512x512">
<link rel="apple-touch-icon-precomposed" href="imgs/icona-180.png">
<link rel="stylesheet" type="text/css" href="theme.css">
</head>
<body>
<div id="fullscreen">
<div id="middlerow">
<p>'.$msg.'</p>
</div>
</div>
</body>
</html>
');
exit(1);
}
?>

View file

@ -0,0 +1,9 @@
<?php
$iniarr=parse_ini_file('sec/mastostartadmin.ini')
or muoribene('Impossibile aprire il file di configurazione.<br>'.$btl,false);
$link=mysqli_connect($iniarr['db_host'],$iniarr['db_admin_name'],$iniarr['db_admin_password'],$iniarr['db_name'],$iniarr['db_port'],$iniarr['db_socket'])
or muoribene('Impossibile connettersi al database: '.mysqli_connect_error().' ['.mysqli_connect_errno().']',false);
mysqli_set_charset($link,'utf8');
?>

View file

@ -0,0 +1,12 @@
<?php
session_name('mastostartadmin');
session_start();
if (!array_key_exists('id',$_SESSION)) {
$_SESSION=array();
session_destroy();
// qui è ok usare muoribene perché per iframe viene caricato da muoribenepar.php
muoribene('Sessione scaduta.<br>Torna alla <a href="index.php">pagina di accesso</a>.',false);
}
?>

59
web/admin/index.php Normal file
View file

@ -0,0 +1,59 @@
<?php
require('include/glob.php');
?>
<!DOCTYPE HTML>
<html lang="it">
<head>
<title>Mastodon Startpage Admin Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="Mastodon Startpage Admin Login">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="icon" type="image/png" href="imgs/icona-32.png" sizes="32x32">
<link rel="icon" type="image/png" href="imgs/icona-192.png" sizes="192x192">
<link rel="icon" type="image/png" href="imgs/icona-512.png" sizes="512x512">
<link rel="apple-touch-icon-precomposed" href="imgs/icona-180.png">
<link rel="stylesheet" type="text/css" href="theme.css?v=<?php echo($cjrand); ?>">
<script language="JavaScript" src="js/alerta.js?v=<?php echo($cjrand); ?>"></script>
<script language="JavaScript">
<!--
function ckfl() {
var emsgs='';
if (document.l.username.value=='') emsgs+='<li>Non hai inserito il nome</li>';
if (document.l.password.value=='') emsgs+='<li>Non hai inserito la password</li>';
if (emsgs!='')
alerta('<ul>'+emsgs+'</ul>');
else
document.l.submit();
}
//-->
</script>
</head>
<body>
<div id="fullscreen">
<div id="middlerow">
<div id="centertit">
Mastodon Startpage Admin Login
</div>
<div id="centerbox">
<form action="login.php" name="l" method="post">
<table id="logintable">
<tr><td>Nome:</td><td class="rtd"><input type="text" name="username" maxlength="64" autofocus></td></tr>
<tr><td>Password:</td><td class="rtd"><input type="password" name="password" maxlength="64"></td></tr>
<tr><td></td><td class="rtd"><input type="button" value="Entra" class="button" onClick="ckfl();"></td></tr>
<tr><td colspan="2" class="tiptd"><a href="passreset.php">Password dimenticata?</a></td></tr>
</table>
</form>
</div>
</div>
</div>
<div id="popup">
<div id="inpopup">
<div id="popupcont">
...
</div>
</div>
</div>
</body>
</html>

90
web/admin/instances.php Normal file
View file

@ -0,0 +1,90 @@
<?php
require('include/glob.php');
require('include/muoribene.php');
require('include/sessionstart.php');
require('include/menu.php');
buildmenu($menu);
require('include/myconn.php');
$res=mysqli_query($link,'SELECT * FROM Instances ORDER BY URI ASC')
or muoribene(mysqli_error($link).'<br>'.$btl,false);
mysqli_close($link);
if (mysqli_num_rows($res)<1) {
$out='<p>Nessuna istanza da mostrare.</p>'.N;
} else {
$out='<table>'.N;
while ($row=mysqli_fetch_assoc($res)) {
$out.='<tr><td>'.$row['URI'].'</td></tr>'.N;
}
$out.='</table>'.N;
}
?>
<!DOCTYPE HTML>
<html lang="it">
<head>
<title>Mastodon Startpage Admin - Main Menu</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="Admin pages for Mastodon Startpage">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="icon" type="image/png" href="imgs/icona-32.png" sizes="32x32">
<link rel="icon" type="image/png" href="imgs/icona-192.png" sizes="192x192">
<link rel="icon" type="image/png" href="imgs/icona-512.png" sizes="512x512">
<link rel="apple-touch-icon-precomposed" href="imgs/icona-180.png">
<link rel="stylesheet" type="text/css" href="theme.css?v=<?php echo($cjrand); ?>">
<script language="JavaScript">
<!--
function chulsh(el,sh) {
if (sh)
el.querySelector('ul').style='display:block';
else
el.querySelector('ul').style='display:none';
}
function ulsh(el,sh) {
if (sh)
el.style='display:block';
else
el.style='display:none';
}
function golang(lang) {
var loc=document.location.href;
loc=loc.replace(/#.*$/,'');
loc=loc.replace(/\/$/,'');
if (document.documentElement.lang=='en') {
if (lang!='en')
document.location.href=loc+'/'+lang;
} else {
if (lang!='en')
document.location.href=loc.substr(0,loc.length-3)+'/'+lang;
else
document.location.href=loc.substr(0,loc.length-3);
}
}
//-->
</script>
</head>
<body>
<nav>
<div id="hmenu">
<ul>
<?php echo($menuout); ?>
</ul>
</div>
</nav>
<div id="fullscreenm">
<div id="middlerow">
<?php echo($out); ?>
</div>
</div>
<div id="footer">
<form action="edinst.php" name="addinst" method="post">
<table><tr><td>Aggiungi unistanza:</td><td><input type="text" name="URI" maxlength="512"></td><td><input type="button" value="Vai" onClick="ckaif();"></td></tr></table>
</form>
</div>
</body>
</html>

4
web/admin/js/alerta.js Normal file
View file

@ -0,0 +1,4 @@
function alerta(msg) {
document.getElementById('popupcont').innerHTML='<h3>Attenzione</h3>'+msg+'<input type="button" class="pupbut" value="Ok" onClick="document.getElementById(\'popup\').style.display=\'none\'">';
document.getElementById('popup').style.display='table';
}

36
web/admin/login.php Normal file
View file

@ -0,0 +1,36 @@
<?php
require('include/glob.php');
require('include/muoribene.php');
$btl='<a href="index.php">Torna al login</a>';
$errs='';
if (!array_key_exists('username',$_POST) || $_POST['username']=='')
$errs.='Non hai specificato il nome<br>'.N;
if (!array_key_exists('password',$_POST) || $_POST['password']=='')
$errs.='Non hai specificato la password<br>'.N;
if ($errs!='') muoribene($errs.$btl,false);
$iniarr=parse_ini_file('sec/mastostartadmin.ini')
or muoribene('Impossibile aprire il file di configurazione.<br>'.$btl,false);
$link=mysqli_connect($iniarr['db_host'],$iniarr['db_admin_name'],$iniarr['db_admin_password'],$iniarr['db_name'],$iniarr['db_port'],$iniarr['db_socket'])
or muoribene('Impossibile connettersi al database: '.mysqli_connect_error().' ['.mysqli_connect_errno().']',false);
mysqli_set_charset($link,'utf8');
$res=mysqli_query($link,'SELECT * FROM Admins WHERE Username=\''.mysqli_real_escape_string($link,$_POST['username']).'\'')
or muoribene(mysqli_error($link).'<br>'.$btl,true);
mysqli_close($link);
if (mysqli_num_rows($res)>1)
muoribene('Record admin duplicato.<br>'.$btl,false);
$row=mysqli_fetch_assoc($res);
if (mysqli_num_rows($res)<1 || !password_verify($_POST['password'],$row['Password']))
muoribene('Nome admin e/o password sbagliati.<br>'.$btl,false);
session_name('mastostartadmin');
session_start();
$_SESSION['id']=$row['ID'];
header('Location: instances.php');
?>

2
web/admin/sec/.htaccess Normal file
View file

@ -0,0 +1,2 @@
Order deny,allow
Deny from all

View file

@ -0,0 +1,6 @@
db_host=localhost
db_port=3306
db_socket=/run/mysqld/mysqld.sock
db_name=mastostart
db_admin_name=MastoStartAdmin
db_admin_password=MastoStartAdmin

213
web/admin/theme.css Normal file
View file

@ -0,0 +1,213 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
height: 100%
}
body {
background-color: white;
color: black;
font-family: Arial, Helvetica, Sans-Serif, sans;
font-size: 14pt;
margin: 0;
padding: 5px;
height: 100%
}
h1,h2,h3,h4,h5,h6 {
text-align: center;
}
a {
text-decoration: none;
color: red;
}
a:hover {
text-decoration: underline;
}
ul {
list-style-type: disc;
padding-left: 0;
margin-left: 14pt;
}
#fullscreen, #fullscreenm {
width: 100%;
height: 100%;
display: table;
}
#fullscreenm {
padding-top: 40px;
}
#middlerow {
display: table-cell;
vertical-align: middle;
text-align: center;
}
#centertit, #centerbox {
font-size: 12pt;
margin-right: auto;
margin-left: auto;
width: 320px;
padding: 5px;
}
#centertit {
font-size: 13pt;
padding: 8px;
background-color: #916f6f;
color: white;
text-shadow: 1px 1px 2px black;
font-weight: bold;
text-align: center;
border-radius: 9px 9px 0 0;
}
#centerbox {
background-color: lightgrey;
border-radius: 0 0 9px 9px;
}
#logintable {
width: 100%;
}
#logintable td {
text-align: right;
width: 1%;
}
#logintable .rtd {
text-align: left;
width: 99%;
}
#logintable .tiptd {
font-size: 10pt;
text-align: center;
width: 100%;
padding-top:10px;
padding-bottom: 10px;
}
input {
width: 100%;
font-size: 11pt;
padding-top: 2px;
padding-bottom: 2px;
}
.button {
font-size: 11pt;
height: 40px;
}
#popup {
z-index: 1;
display: none;
top: 0px;
position: fixed;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.75);
color: white;
padding: 0;
font-size: 12pt;
}
#inpopup {
display: table-cell;
vertical-align: middle;
}
#popupcont {
position: relative;
margin-left: auto;
margin-right: auto;
border: 1px solid gray;
width: 200px;
background-color: white;
border-radius: 9px;
color: black;
padding: 5px;
text-align: left;
}
#footer {
color: white;
position: fixed;
height: 40px;
width: 100%;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.85);
line-height: 40px;
vertical-align: middle;
}
#hmenu {
font-size: 14pt;
background-color: rgba(0,0,0,0.85);
color: white;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 40px;
margin: 0;
padding: 0;
/*box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4);*/
/*padding-left: 40px;*/
z-index: 2;
/*display: none;*/
}
#hmenu ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: visible;
}
#hmenu ul li {
width: 80pt;
height: 40px;
text-align: center;
display: table-cell;
vertical-align: middle;
color: #3088D4;
}
#hmenu ul li:hover {
background-color: rgba(255,255,255,0.10);
cursor: default;
}
#hmenu ul li a {
width: 80pt;
line-height: 40px;
display: block;
color: #3088D4;
}
#hmenu .ula {
position: absolute;
top: 40px;
background-color: rgba(0,0,0,0.85);
display: none;
}
#hmenu .ulb {
background-color: rgba(0,0,0,0.85);
left: 80pt;
position: relative;
top: -40px;
display: none;
}
#hmenu .ula li, .ulb li {
width: 80pt;
height: 40px;
display: block;
float: none;
text-align: center;
line-height: 40px;
vertical-align: middle;
}
#hmenu .ula li:hover, .ulb li:hover {
text-decoration: underline;
}
#hmenu .hil {
background-color: rgba(255,255,255,0.10);
color: #97C3E9;
}
#hmenu .hil:hover {
cursor: default;
text-decoration: none;
}
#hmenu .ula li.hil:hover, .ulb li.hil:hover {
text-decoration: none;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 11 KiB

BIN
web/imgs/icona-180.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

BIN
web/imgs/icona-192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
web/imgs/icona-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,005 B

BIN
web/imgs/icona-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -1,6 +1,6 @@
<?php
const N="\n";
define('N',"\n");
$instpath='/mastostart';
$path=preg_replace('/^'.preg_quote($instpath,'/').'/','',$_SERVER['REQUEST_URI']);
@ -10,7 +10,7 @@ for ($i=0; $i<$ndir; $i++)
$prepath.='../';
$menu=array(
'guide'=>array('liadd'=>null, 'href'=>$instpath, 'title'=>'Guide', 'selected'=>false, 'submenu'=>null),
'guide'=>array('liadd'=>null, 'href'=>$instpath.'/', 'title'=>'Guide', 'selected'=>false, 'submenu'=>null),
'instances'=>array('liadd'=>null, 'href'=>$instpath.'/instances', 'title'=>'Instances', 'selected'=>false, 'submenu'=>null),
'about'=>array('liadd'=>null, 'href'=>$instpath.'/about', 'title'=>'About', 'selected'=>false, 'submenu'=>null),
'language'=>array('liadd'=>null, 'href'=>null, 'title'=>'Language', 'selected'=>false, 'submenu'=>array(
@ -25,7 +25,7 @@ function tradmenu($lang) {
switch ($lang) {
case 'it':
$menu['guide']['title']='Guida';
$menu['guide']['href'].='/it';
$menu['guide']['href'].='it';
$menu['instances']['title']='Istanze';
$menu['instances']['href'].='/it';
$menu['about']['title']='Info';
@ -42,6 +42,7 @@ switch($path) {
'fp'=>'home_en.php',
'lang'=>'en',
'atit'=>' - Guide',
'desc'=>'A thorough introduction to Mastodon',
'js'=>array('shsum','guideanchors','scrolltrack')
);
$menu['guide']['liadd']='onclick="shsum()" onmouseover="this.style.cursor=\'pointer\'; this.style.textDecoration=\'underline\'" onmouseout="this.style.textDecoration=\'none\'"';
@ -56,6 +57,7 @@ switch($path) {
'fp'=>'home_it.php',
'lang'=>'it',
'atit'=>' - Guida',
'desc'=>'Una approfondita introduzione a Mastodon',
'js'=>array('shsum','guideanchors','scrolltrack')
);
tradmenu('it');
@ -71,6 +73,7 @@ switch($path) {
'fp'=>'instances_en.php',
'lang'=>'en',
'atit'=>' - Instances',
'desc'=>'Recommended Mastodon Instances',
'js'=>array()
);
$menu['instances']['href']=null;
@ -84,6 +87,7 @@ switch($path) {
'fp'=>'instances_it.php',
'lang'=>'it',
'atit'=>' - Istanze',
'desc'=>'Istanze Mastodon consigliate',
'js'=>array()
);
tradmenu('it');
@ -98,6 +102,7 @@ switch($path) {
'fp'=>'about_en.php',
'lang'=>'en',
'atit'=>' - About us',
'desc'=>'Infos about Mastodon Startpages authors, contributors, license',
'js'=>array()
);
$menu['about']['href']=null;
@ -111,6 +116,7 @@ switch($path) {
'fp'=>'about_it.php',
'lang'=>'it',
'atit'=>' - Info',
'desc'=>'Informazioni sugli autori, i collaboratori e la licenza di Mastodon Startpage',
'js'=>array()
);
tradmenu('it');
@ -125,6 +131,7 @@ switch($path) {
'fp'=>'404.php',
'lang'=>'en',
'atit'=>' - 404',
'desc'=>'Page not found',
'js'=>array()
);
break;
@ -178,9 +185,12 @@ $cjrand=rand(0,999999);
<head>
<title>Mastodon Startpage<?php echo($cont['atit']); ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="A thorough introduction to Mastodon">
<meta name="description" content="<?php echo($cont['desc']); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="shortcut icon" href="<?php echo($prepath); ?>favicon.ico">
<link rel="icon" type="image/png" href="<?php echo($prepath); ?>imgs/icona-32.png" sizes="32x32">
<link rel="icon" type="image/png" href="<?php echo($prepath); ?>imgs/icona-192.png" sizes="192x192">
<link rel="icon" type="image/png" href="<?php echo($prepath); ?>imgs/icona-512.png" sizes="512x512">
<link rel="apple-touch-icon-precomposed" href="<?php echo($prepath); ?>imgs/icona-180.png">
<link rel="stylesheet" type="text/css" href="<?php echo($prepath); ?>theme.css?v=<?php echo($cjrand); ?>">
<?php
foreach ($cont['js'] as $val)

View file

@ -333,7 +333,13 @@ a:active {
#hmenu {
font-size: 12pt;
}
/*#hmenu li, .ula li, .ulb li {
#hmenu ul li,
#hmenu ul li a,
#hmenu .ula li,
#hmenu .ulb li {
width: 60pt;
}*/
}
#hmenu .ulb {
left: 60pt;
}
}