mastblocksmerge.wip.sh 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #!/bin/bash
  2. # This program is free software: you can redistribute it and/or modify
  3. # it under the terms of the GNU General Public License as published by
  4. # the Free Software Foundation, either version 3 of the License, or
  5. # (at your option) any later version.
  6. # This program is distributed in the hope that it will be useful,
  7. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. # GNU General Public License for more details.
  10. # You should have received a copy of the GNU General Public License
  11. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. MASTHOME='/var/lib/mastodon'
  13. MASTENVFP="$MASTHOME/live/.env.production"
  14. SISTERSFP="istanzesorelle"
  15. LOCAL=0
  16. INTERACTIVE=0
  17. HELP="SINTASSI
  18. mastblocksmerge.sh [opzioni]
  19. DESCRIZIONE
  20. Questo script integra i dati di una o più blocklist esterne nella
  21. tabella domain_blocks di mastodon.
  22. Legge i domini delle istanze di cui recuperare la blocklist da un file
  23. di inizializzazione, per default \"$SISTERSP\" (formato del file:
  24. un dominio per riga), prova a recuperare ciascuna blocklist da
  25. https://[dominio]/domain_blocks.txt, costruisce dalle liste recuperate
  26. un\'unica lista senza duplicati, si collega al db di mastodon e scrive
  27. nella tabella domain_blocks i dati relativi alle istanze bloccate che
  28. non sono già presenti nella tabella stessa.
  29. Per la connessione al db di mastodon legge i dati necessari dal file
  30. di configurazione di mastodon, per default
  31. \"$MASTENVFP\"
  32. È pensato per essere eseguito periodicamente da un cron job, come
  33. utente mastodon oppure root oppure altro utente che abbia accesso in
  34. lettura al file di configurazione di mastodon.
  35. OPZIONI
  36. -H, --home
  37. Definisce la home di mastodon (per default \"$MASTHOME\")
  38. e di conseguenza il percorso del suo file di configurazione
  39. (per default \"$MASTENVFP\").
  40. È comunque possibile specificare individualmente il percorso
  41. del file di configurazione di mastodon con l\'opzione che segue.
  42. -e, --envfp
  43. Definisce il percorso del file di configurazione di mastodon in uso.
  44. -s, --sistersfp
  45. Definisce il percorso del file di inizializzazione da cui leggere
  46. la lista dei domini delle istanze sorelle.
  47. -l, --local
  48. Interpreta il file di inizializzazione come lista di file locali
  49. contenenti blacklist (formato: un file per riga).
  50. -i, --interactive
  51. Modalità interattiva: se vengono nelle blocklist vengono trovate
  52. istanze ancora non presenti nel database di mastodon, viene chiesto
  53. per ciascuna se aggiungerla o meno.
  54. -h, --help
  55. Mostra questo aiuto ed esce."
  56. args=("$@")
  57. i=0
  58. while [ $i -lt ${#args[@]} ]; do
  59. if [ "${args[$i]:0:1}" == "-" ]; then
  60. case "${args[$i]}" in
  61. "-H" | "--home" )
  62. if [ -z "${args[$i+1]}" ]; then
  63. echo "L'opzione \"${args[$i]}\" richiede un parametro (usa \"-h\" per l'aiuto)."
  64. exit 1
  65. else
  66. ((i++))
  67. MASTHOME=$(echo "${args[$i]}" | sed -e 's/\/$//')
  68. MASTENVFP="$MASTHOME/live/.env.production"
  69. fi
  70. ;;
  71. "-e" | "--envfp" )
  72. if [ -z "${args[$i+1]}" ]; then
  73. echo "L'opzione \"${args[$i]}\" richiede un parametro (usa \"-h\" per l'aiuto)."
  74. exit 1
  75. else
  76. ((i++))
  77. MASTENVFP="${args[$i]}"
  78. fi
  79. ;;
  80. "-s" | "--sistersfp" )
  81. if [ -z "${args[$i+1]}" ]; then
  82. echo "L'opzione \"${args[$i]}\" richiede un parametro (usa \"-h\" per l'aiuto)."
  83. exit 1
  84. else
  85. ((i++))
  86. SISTERSFP="${args[$i]}"
  87. fi
  88. ;;
  89. "-l" | "--local" )
  90. LOCAL=1
  91. ;;
  92. "-i" | "--interactive" )
  93. INTERACTIVE=1
  94. ;;
  95. "-h" | "--help" )
  96. echo "$HELP"
  97. exit 0
  98. ;;
  99. *)
  100. echo "\"${args[$i]}\": opzione sconosciuta (usa \"-h\" per l'aiuto)."
  101. exit 1
  102. ;;
  103. esac
  104. else
  105. echo "\"${args[$i]}\": opzione sconosciuta (usa \"-h\" per l'aiuto)."
  106. exit 1
  107. fi
  108. ((i++))
  109. done
  110. [ ! -e "$MASTENVFP" ] && echo "\"$MASTENVFP\" non esiste, muoio (usa \"-h\" per l'aiuto)." && exit 1
  111. [ ! -f "$MASTENVFP" ] && echo "\"$MASTENVFP\" non è un file, muoio (usa \"-h\" per l'aiuto)." && exit 1
  112. [ ! -r "$MASTENVFP" ] && echo "\"$MASTENVFP\" non è leggibile, muoio (usa \"-h\" per l'aiuto)." && exit 1
  113. [ ! -e "$SISTERSFP" ] && echo "\"$SISTERSFP\" non esiste, muoio (usa \"-h\" per l'aiuto)." && exit 1
  114. [ ! -f "$SISTERSFP" ] && echo "\"$SISTERSFP\" non è un file, muoio (usa \"-h\" per l'aiuto)." && exit 1
  115. [ ! -r "$SISTERSFP" ] && echo "\"$SISTERSFP\" non è leggibile, muoio (usa \"-h\" per l'aiuto)." && exit 1
  116. DB_HOST=`grep 'DB_HOST' "$MASTENVFP"|sed -e 's/[^=]*=//'`
  117. DB_PORT=`grep 'DB_PORT' "$MASTENVFP"|sed -e 's/[^=]*=//'`
  118. DB_NAME=`grep 'DB_NAME' "$MASTENVFP"|sed -e 's/[^=]*=//'`
  119. DB_USER=`grep 'DB_USER' "$MASTENVFP"|sed -e 's/[^=]*=//'`
  120. DB_PASS=`grep 'DB_PASS' "$MASTENVFP"|sed -e 's/[^=]*=//'`
  121. IFS=$'\n'
  122. function decode {
  123. #dominio
  124. record[0]=$(echo "$1" | sed -e 's/\t.*//')
  125. #data creazione
  126. record[1]=$(echo "$1" | sed -e 's/^[^\t]*\t\([^\t]*\).*/\1/')
  127. #data ultima modifica
  128. record[2]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
  129. #tipo di blocco
  130. record[3]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
  131. #rifiuto media
  132. record[4]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
  133. #rifiuto reports
  134. record[5]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
  135. #commento pubblico
  136. record[6]=$(echo "$1" | sed -e 's/^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t\([^\t]*\).*/\1/')
  137. if [ "${record[4]}" == "f" ]; then
  138. record[4]="No"
  139. elif [ "${record[4]}" == "t" ]; then
  140. record[4]="Si"
  141. fi
  142. if [ "${record[5]}" == "f" ]; then
  143. record[5]="No"
  144. elif [ "${record[5]}" == "t" ]; then
  145. record[5]="Si"
  146. fi
  147. if [ "${record[3]}" == "0" ]; then
  148. record[3]="Silenziata"
  149. elif [ "${record[3]}" == "1" ]; then
  150. record[3]="Sospesa"
  151. elif [ "${record[3]}" == "2" ]; then
  152. record[3]="Nessuno"
  153. fi
  154. }
  155. for sisdom in $(grep -P '^[^#]+[^\s]+' "$SISTERSFP"); do
  156. if [ $LOCAL -eq 0 ]; then
  157. blocks+="$(curl --connect-timeout 3 -s "https://$sisdom/domain_blocks.txt" | grep -P '^[^#]+[^\s]+')$IFS"
  158. else
  159. blocks+="$(cat "$sisdom" | grep -P '^[^#]+[^\s]+')$IFS"
  160. fi
  161. done
  162. blocks=$(echo "$blocks" | head -n -1 | sort -u)
  163. echo "$blocks"
  164. echo "~~~~~~~~~~~~~~~~~~~~"
  165. okblocks=''
  166. for line in $blocks; do
  167. dom=$(echo "$line" | sed -e 's/\t.*//' -e 's/\./\\./g')
  168. echo "$okblocks" | grep -P "^$dom\t"
  169. if [ $? -ne 0 ]; then
  170. entries=$(echo "$blocks" | grep -P "^$dom\t")
  171. howmany=$(echo "$entries" | wc -l)
  172. if [ $howmany -gt 1 ]; then
  173. if [ $INTERACTIVE -eq 1 ]; then
  174. i=0
  175. for entry in $entries; do
  176. ((i++))
  177. echo "$i: $entry"
  178. done
  179. read
  180. else
  181. # qui ci vorrebbe codice "intelligente" che sceglie la entry più recente, ma per ora così
  182. okblocks+="$line$IFS"
  183. fi
  184. fi
  185. fi
  186. done
  187. okblocks=$(echo "$okblocks" | head -n -1 | sort)
  188. echo "$okblocks"
  189. echo "~~~~~~~~~~~~~~~~~~~~"
  190. exit
  191. 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')
  192. i=0
  193. for line in $allblocks; do
  194. dom=$(echo "$line" | sed -e 's/\t.*//' -e 's/\./\\./g')
  195. echo "$blocks" | grep -P "^$dom\t" &>/dev/null
  196. [ $? -ne 0 ] && newblocks+="$line$IFS" && ((i++))
  197. done
  198. newblocks=$(echo "$newblocks" | head -n -1 | sort)
  199. [ $i -eq 0 ] && echo "Non ho trovato nessuna nuova istanza bloccata." && exit 0
  200. echo "Ho trovato $i istanza/e bloccata da aggiungere."
  201. if [ $INTERACTIVE -eq 1 ]; then
  202. for line in $newblocks; do
  203. decode "$line"
  204. 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]}"
  205. ask=1
  206. while [ $ask -eq 1 ]; do
  207. read -p "Vuoi aggiungere questa istanza alla tabella delle istanze bloccate? [S/n] " inp
  208. echo "$inp" | grep -P '^[sSnN]{0,1}$' &>/dev/null
  209. [ $? -eq 0 ] && ask=0
  210. done
  211. if [ "$inp" == "" ] || [ "$inp" == "s" ] || [ "$inp" == "S" ]; then
  212. buf+="$line$IFS"
  213. fi
  214. done
  215. newblocks=$(echo "$buf" | head -n -1)
  216. fi
  217. 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 ' ' )"